fscanf不会阻止调用线程

时间:2016-04-30 11:44:49

标签: c++ multithreading

我正在用C ++处理fscanf函数,我对fscanf感到困惑。为什么它在流完全为空时不会阻塞调用线程。

在我的期望中,主线程应该在fscanf函数上被阻塞,它将在3秒后被释放,因为子线程将在3秒后写入文件流。

但是现实,它似乎并不像我预期的那样。请有人告诉我为什么?

以下是我的代码行:

#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;
}

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

因为人们可能不明白为什么我认为fscanf应该阻止调用线程。

这就是我有上述问题的原因。

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

程序停止输入。

1 个答案:

答案 0 :(得分:3)

您正在使用常规文件,因此当您结束时fscanf会返回EOF。事实上,另一个线程在几秒钟内会附加一些数据是无关紧要的,而C库无论如何都无法知道它。

标准输入块,因为当它连接到控制台时它不会结束(直到用户按下Ctrl-D),所以如果你要求更多输入并且它还没有准备好接受它等待(想想它就好像它是一个磁盘上的文件非常提供数据的速度很慢)。

此外,使用实际文件支持的FILE *进行跨线程通信似乎是一个坏主意;除了效率问题和头痛相对于在两个线程之间共享FILE *的线程安全性之外,它还严重映射到手头的问题;你似乎想要的是两个线程之间的类似FIFO的通信通道,而不是数据的存储设备。

如果你想在两个线程之间进行FIFO通信,你可以使用 - 例如 - 匿名管道或只是线程安全的消息队列。