2013-11-25 82 views
0

缓冲IO流在fork()上有奇怪的行为。fork()和缓冲IO流

在下面显示的示例代码片段中,正在读取的文件大小为252个字节。在fork()之后,孩子正在成功地阅读一条线并在屏幕上进行打印。但是,当控件返回到父项时,由于某种原因,文件偏移量被设置为文件的结尾,并且父进程无法从流中读取任何内容。如果fork()创建了一个文件描述符的副本(可以使用系统调用read()write()复制相同的程序,可以正常工作),可以期望父进程从流中读取下一行,但这似乎并未发生。当控件到达父级时,文件偏移量被设置为文件末尾。有人可以对此有所了解吗?

int main(void) 
{  
    char buffer[80]; 
    FILE *file; 
    pid_t pid; 
    int status; 

    /* Open the file: */ 
    file = fopen(FILENAME, "r"); 

    if ((pid = fork()) == 0){ 
     fgets(buffer, sizeof(buffer), file); 
     printf("%s", buffer); 
    } 
    else{ 
     waitpid(pid, &status, 0); 
     printf("Offset [%d]\n", ftell(file)); 

     fgets(buffer, sizeof(buffer), file); 
     printf("%s", buffer); 
    } 
} 

回答

0

子进程中的fgets()完全缓冲,因为它从文件读取数据。在我的系统上,一个完全缓冲的缓冲区大小为1024 ..因此,一个read()包含fgets()缓冲区中文件的全部内容(252个字节)。所以当控件回到父对象时,偏移量被设置为文件的结尾。

在子进程返回前做一个fflush()函数,确保fgets()缓冲区中的数据被丢弃,因此当控件到达父级时,会正确设置文件名称。