2016-04-30 8 views
0

私はfscanfについてC++でfscanf関数を扱っています。ストリームが絶対に空である間に呼び出しスレッドをブロックしないのはなぜですか?fscanfは呼び出しスレッドをブロックしません

メインスレッドはfscanf関数でブロックする必要があります。ファイルストリームは3秒後に子スレッドによって書き込まれるため、3秒後に解放されます。

しかし、実際には、私は期待どおりではないようです。なぜ誰かに教えてください?私は、関数fscanfは、呼び出しをブロックすべきだと思う理由の人が理解していない可能性があるので

#include <windows.h> 
#include <iostream> 
#include <stdio.h> 

DWORD WINAPI subroutine(LPVOID data) 
{ 
    FILE* file = (FILE*)data; 

    std::cout << "I'll send you something after 3s" << std::endl; 
    Sleep(3000); 

    if (file != NULL) 
    { 
     std::cout << "I'm writing now" << std::endl; 

     char* sentence = "Hello"; 
     fputs(sentence, file); 
    } 
} 

int main() 
{ 
    FILE* file = tmpfile(); 

    if (file != NULL) 
    { 
     CreateThread(NULL, 0, subroutine, file, 0, NULL); 

     char something[50]; 

     std::cout << "Blocking..." << std::endl; 

     rewind(file); 
     fscanf(file, "%s", something); 

     std::cout << "Message is " << something << std::endl; 
    } 
    std::cout << "Done" << std::endl; 

    if (file != NULL) 
    { 
     fclose(file); 
    } 
    return 0; 
} 

============

次は、コードの私のラインであります糸。

これは私に上記の質問がある理由です。

int main() 
{ 
    char something[50]; 
    fscanf(stdin, "%s", something); 
    std::cout << something << std::endl; 
    return 0; 
} 

何か入力するプログラムが停止しました。

+0

なぜ呼び出しスレッドをブロックすべきですか?読み取ったアイテムの数を返すか、 'EOF'に達すると' EOF'を返します。 ['fscanf'](http://www.cplusplus.com/reference/cstdio/fscanf/)のドキュメントを見ましたか? –

答えて

3

普通のファイルを使用しているため、末尾に来たときにfscanfEOFを返します。数秒でいくつかのデータを追加する別のスレッドがあるという事実は無関係であり、Cライブラリはそれをどうにか知る方法がありません。

標準入力ブロックとは、コンソールに接続されても終了しないため(ユーザーがCtrl-Dを押すまで)、入力を待っていて準備ができていない場合あたかもそれがディスク上のファイルであるかのように)極端に

さらに、クロススレッド通信用の実際のファイルに裏打ちされたFILE *を使用することは悪い考えです。 2つのスレッド間でFILE *を共有するスレッドの安全性に関連する効率の問題と頭痛以外にも、それは手元の問題に悪い影響を与えます。ここで欲しいと思うのは、データ用の記憶装置ではなく、2つのスレッド間のFIFOのような通信チャネルです。

2つのスレッド間でFIFO通信を行う場合は、匿名パイプやスレッドセーフメッセージキューなどを使用できます。

関連する問題