2017-04-30 77 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,該方法將讀取文件的不同部分,作爲讀將更新位置在另一。

但是,如果你正在閱讀線條,你會陷入困境。

除非事先知道行的長度(即它們具有固定的長度),否則您可能會讀取部分行,而讓其他進程可能讀取其他部分。要解決該問題,您需要一次讀取一個字符,或者在閱讀後回到行邊界。這兩種情況都會受到競爭條件的影響:另一個過程可能會在您的閱讀或閱讀與尋求之間進行閱讀。