【问题标题】:c stdout to stdin realtimec 标准输出到标准输入实时
【发布时间】:2016-11-04 18:02:05
【问题描述】:

我制作了两个程序,其中一个名为生成器,每秒打印一些文本

int main(int argc, char** argv) {

    for(int i = 0; i < 10 ; i++) {
         printf("something\n");
         sleep(1);
    }

  return (EXIT_SUCCESS);
}

然后有一个第二个程序现在称之为消费者,它应该从标准输入中读取,添加一些其他文本并重新打印它。 让它看起来像这样:

 int main(int argc, char** argv) {


   char line[BUFSIZ];

   while(scanf("%s",line) != -1){
       printf("you entered %s \n",line);
   }

    return (EXIT_SUCCESS);
}

当我编译它们并尝试只运行像 ./generator 这样的生成器时,它会按我的预期工作。每一秒都会有一些东西打印到控制台。 但是当我尝试像 ./generator | 一样运行它们时。/消费者 它没有像我预期的那样工作。我等了 10 秒,然后得到 10 行 you enter something 我想每秒打印一次“你输入了一些东西”。

您能解释一下为什么会这样,或者更好地告诉我如何实现预期的行为吗?

【问题讨论】:

    标签: c linux io pipe


    【解决方案1】:

    C I/O 被缓冲。使用终端 I/O 时,缓冲规则是line buffered,因此在发送\n 时会将内容刷新到输出。当您使用管道时,缓冲规则是full buffered,因此只有在缓冲区已满时才会刷新内容(无论内容是什么)。

    您可以:

    1. flush(stdout) 每次需要真正写出数据时,
    2. 在任何写入之前调用setvbuf 来更改缓冲区规则。

    【讨论】:

      【解决方案2】:

      您的 printf 的输出正在被缓冲,并且只有在缓冲区已满时才会输出。您可以在消费者中调用 setbuf()(在开头一次),将 NULL 作为第二个参数,将 stdout 上的缓冲区大小设置为 NULL。

      #include <stdio.h>
      setbuf( stdout, NULL );
      

      这将导致写入标准输出(即您的 printf)的输出立即出来。或者,您可以写入 stderr,默认情况下它的缓冲区大小为 NULL。 (或者,作为另一种选择,您可以在每次要将缓冲区内容刷新到终端时在 stdout 上调用 fflush)。

      【讨论】:

      • 或者您可以使用 stdbuf -o0 ./generator | 关闭命令行缓冲./消费者
      • @RomanHocke 等等,有一个程序可以改变另一个进程 pre-exec 的用户模式行为吗?嗯,这很有趣......
      【解决方案3】:

      输出是缓冲的,因此 stdio 库会等待,直到它有一堆数据,通常是 4 KB,然后立即输出。

      只要您希望输出实际输出,只需添加对 fflush 的调用:

      fflush(stdout);
      

      当输出直接发送到终端时,它的工作方式不同。然后标准输出被行缓冲,因此在每个行尾字符之后刷新缓冲区。

      【讨论】:

        【解决方案4】:

        您应该使用线程来并行执行程序的某些部分:

        #include <iostream>
        #include <thread>
        #include <unistd.h>
        
        using namespace std;
        void Print() {
        
        
        sleep(1);
        cout << "Thread trolling you!!!\n";
        Print();
        }
        
        int main () {
        string g;
        thread ttt(Print);  //create thread, from now Print() runs parallel to
        cin >> g;           //the rest of int main()
        cout << g;
        ttt.join();         //join threads
        return (0);
        }
        

        【讨论】:

        • 只是一个例子,不能直接解决您的问题。
        • 没有最大深度限制的递归函数?我不认为 C++ 保证了尾调用优化,所以这有点……不好。
        猜你喜欢
        • 1970-01-01
        • 2013-09-18
        • 2021-12-13
        • 2014-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多