Linux execv之后,管道缓冲区中的内容消失

Linux execv之后,管道缓冲区中的内容消失,linux,pipe,execv,Linux,Pipe,Execv,有两个进程,父进程和子进程 父进程stdin中有一些数据。内容是: the 1 line the 2 line the 3 line the 4 line 父进程代码: //parent fgets(buffer, 1000, stdin); printf("I have data:%s", buffer); //print "I have data:the 1 line" if(!fork()) { fgets(buffer, 1000, stdin); printf(

有两个进程,父进程和子进程 父进程stdin中有一些数据。内容是:

the 1 line
the 2 line
the 3 line
the 4 line
父进程代码:

//parent
fgets(buffer, 1000, stdin);
printf("I have data:%s", buffer);   //print "I have data:the 1 line" 
if(!fork())
{
    fgets(buffer, 1000, stdin);
    printf("I have data:%s", buffer);   //print "I have data:the 2 line"
    execv("child", NULL);          
}
else
{
    exit(0);
}
//child
main()
{
    fgets(buffer, 1000, stdin);  //blocked if parent stdin content size<4096
    printf("I have no data:%s", buffer);  
}
子进程代码:

//parent
fgets(buffer, 1000, stdin);
printf("I have data:%s", buffer);   //print "I have data:the 1 line" 
if(!fork())
{
    fgets(buffer, 1000, stdin);
    printf("I have data:%s", buffer);   //print "I have data:the 2 line"
    execv("child", NULL);          
}
else
{
    exit(0);
}
//child
main()
{
    fgets(buffer, 1000, stdin);  //blocked if parent stdin content size<4096
    printf("I have no data:%s", buffer);  
}
//子对象
main()
{

fgets(buffer,1000,stdin);//如果父stdin content size
fgets
是一个stdio函数,那么它将使用stdio缓冲区,该缓冲区位于进程的地址空间中。当您执行时,该缓冲区将与原始程序的其余部分一起消失,被执行的程序将分配自己的stdio缓冲区


如果您的文件是可查找的,则在exec可能提供帮助之前,
fseek
相对于
SEEK\u CUR
定位0(它可以将基础fd重新定位到正确的点,以便从stdio停止的位置继续读取).

谢谢您的回答。但在我的代码中,父进程stdin的源是一个不可查找的管道。还有另一种方法吗?在管道中,让子进程保留数据的唯一方法是父进程不读取它。这意味着它必须进行无缓冲的单字符读取,以便它可以在
'\n'
上正确停止。请尝试
setvbuf(stdin,0,_IONBF,0)
看看这是否有帮助。但是如果父进程stdin的内容大小大于4K,子进程可以读取数据。为什么?这是stdio缓冲区的大小。第2行末尾到第二个4K块开始之间的所有内容都将丢失。