2017-04-30 47 views
0

让说,我有一个父进程,然后才能从同一个文件中读取创建子进程的一些数字。从孩子改变偏移处理

  1. 当每个进程从文件描述符中读取时,偏移量是否在所有兄弟进程之间发生了变化?

  2. 等等,是有可能,每个进程将读取的唯一线,或者,如果没有同步的应用程序,每个进程将读取同样的思路像他的兄弟姐妹?

    id = fork(); 
    
    if (id < 0) 
        exit(EXIT_FAILURE); 
    
    if (pipe(fd) == -1) 
        exit(EXIT_FAILURE); 
    
    switch (id) { 
    case 0: 
        //child process 
        readFromFile(filename); 
        exit(0); 
        break; 
    default: 
        //Parent process doing something.. 
        break; 
    } 
    

回答

1

在一个POSIX系统,通过一个fork调用由子进程继承文件描述符指向同一个文件描述符在全系统表。下面是从Linux手册页相关的报价为开放式(2):

术语打开文件的描述是使用POSIX指 在打开文件的全系统表中的项目之一... 当文件描述符被复制(用DUP(2)或类似的),则 重复是指相同的开放文件描述作为原始 文件描述符,并且两个文件描述符因此共享 文件偏移量和文件状态标志。这种共享也可以进程之间发生 :经由叉(2)创建继承父的文件描述符 重复子进程,和这些重复 指代相同的打开的文件的描述。

这意味着,父母和孩子分享文件偏移量相同的信息,并在一个读将改变所有其它进程的偏移看到。如果在读取之间没有并行读取进程,则不会有两个进程读取相同的数据。

您可以在下面的测试程序,它打印在命令行给出的文件的前20个字符在行动看到这一点。 (如果位置信息不共享,则会打印前10个字符两次)。

#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

char buffer[256]; 

int 
main(int argc, char ** argv) 
{ 
    int fd = open(argv[1], O_RDONLY); 
    fork(); 
    read(fd, buffer, 10); 
    write(1, buffer, 10); 
    return 0; 
} 

无论其,这是一个巨大的“但是”,这仅适用于低级别的系统调用接口读取文件:open(2)read(2)等,如果你正在使用缓冲更高级别界面,如fgets和其他功能stdio.h,事情变得复杂。当进程分叉,即使他们继承指向单一的全系统,共享的内核文件信息结构文件描述符的副本,他们也会沿用使用stdio.h电话用户空间的缓存信息独立份,并且这个缓冲信息包括它自己的偏移(显然是缓冲区),它们在进程之间不同步。

0

等等,是有可能,每个过程将从一个读取的唯一线

作为KA Buhr的says,该方法将读取文件的不同部分,作为读将更新位置在另一。

但是,如果你正在阅读线条,你会陷入困境。

除非事先知道行的长度(即它们具有固定的长度),否则您可能会读取部分行,而让其他进程可能读取其他部分。要解决该问题,您需要一次读取一个字符,或者在阅读后回到行边界。这两种情况都会受到竞争条件的影响:另一个过程可能会在您的阅读或阅读与寻求之间进行阅读。