c stdout to stdin realtime

时间:2016-11-04 18:02:05

标签: c linux io pipe

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

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行你输入的东西 我想打印&#34;你输入的东西&#34;每一秒。

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

4 个答案:

答案 0 :(得分:4)

C I / O被缓冲。使用终端I / O时,缓冲规则行缓冲,因此在发送\n时会刷新内容以输出。当您使用管道时,缓冲规则是完全缓冲,以便仅在缓冲区已满(无论内容是什么)时刷新内容。

你可以:

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

输出被缓冲,因此stdio库会等待它有一堆数据,通常是4千字节,然后立即输出。

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

fflush(stdout);

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

答案 3 :(得分:-3)

您应该使用线程并行执行程序的各个部分:

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