2016-11-04 129 views
5

我必须让两个方案其中一个名为发生器,它打印一些文字每秒Ç标准输出到标准输入实时

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行你输入了一些东西 我想打印“你每秒输入一些东西”。

你能解释一下为什么这样,或者甚至更好地告诉我如何达到预期的行为?

回答

3

来自printf的输出被缓冲,并且只在缓冲区满时出来。你可以在消费者中调用setbuf()(一开始一次),使用NULL作为第二个参数,将stdout上的缓冲区大小设置为NULL。

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

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

+1

或者你也可以使用stdbuf -o0 ./generator关闭缓冲命令行| 。/ consumer –

+0

@RomanHocke等待有一个程序改变另一个进程预执行程序的用户模式行为?那么这很有趣... –

2

输出被缓冲,所以stdio库一直等到它有一堆数据,通常是4千字节,然后立即输出。

,每当你想输出实际输出的调用只需添加到fflush

fflush(stdout); 

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

4

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

您可以:

  1. 每次你必须真正写在数据时间flush(stdout)
  2. 改变任何写操作之前,要setvbuf通话缓冲区纪律。
-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); 
} 
+0

只是一个例子不是你的问题的直接解决方案。 – Legolas

+1

递归函数没有有限的最大深度?我不认为C++保证了尾部呼叫优化,所以这有点不好。 – hyde

+0

此外这个答案似乎错过了很不好的问题... – hyde

相关问题