2013-07-25 65 views
2

我們最近在我的應用操作系統設計類中引入fork(),並且我對它的理解不是很好。我們需要使用它在C文件中創建四個獨立的進程,然後將這些進程中的三個寫入命名管道,而第四個進程則從中讀取。使用fork()使4個進程?

這是到目前爲止,我已經試過代碼:

// creating the named pipe 
mknod("/tmp/namedpipe", S_IFIFO | 0600, 0); 
int myPipe; 

const char* colour; 

pid_t p1, p2; 

p1 = fork(); 
if (p1 < 0) 
{ 
    printf("Fork failed\n"); 
} 
else if (p1 == 0) // this is the child of p1, we'll call it "red" 
{ 
    printf("\nPid %d %s", getpid(), "(red) started\n"); 
    myPipe = open("/tmp/namedpipe", O_WRONLY); 
    colour = "RED\n"; 
    write(myPipe, colour, strlen(colour) +1); 
    close(myPipe); 
} 
else // the is the parent of p1, we'll call it "green" 
{ 
    printf("\nPid %d %s", getpid(), "(red) started\n"); 
    myPipe = open("/tmp/namedpipe", O_WRONLY); 
    colour = "RED\n"; 
    write(myPipe, colour, strlen(colour) +1); 
    close(myPipe); 

    p2 = fork(); 
    if (p2 < 0) 
    { 
     printf("Fork failed\n"); 
    } 
    else if (p2 == 0) // this is the child of p2, we'll call it "blue" 
    { 
     printf("\nPid %d %s", getpid(), "(blue) started\n"); 
     myPipe = open("/tmp/namedpipe", O_WRONLY); 
     colour = "BLU\n"; 
     write(myPipe, colour, strlen(colour) +1); 
     close(myPipe); 
    } 
    else // the is the parent of p2, we'll call it "reader" 
    { 
     printf("This is the reader process"); 
     myPipe = open("/tmp/namedpipe", O_RDONLY); 
     char nextChar; 
     while (read(myPipe, &nextChar, 1) == 1) 
     printf("%c", nextChar); 
     close(myPipe); 
    } 
} 

此代碼似乎如果你註釋掉所有管道相關的語句做工精細,但除此之外,它執行前兩個打印語句,然後掛起,強制CTRL-C。我不確定問題在於分叉,還是與我寫作和閱讀管道的方式有關。請告訴我。

回答

4

命名管道打開,但不O_NONBLOCK的進程間同步。如果一個進程試圖打開進行寫入,它將會阻塞,直到其他進程嘗試打開進行讀取。如果訂單逆轉,讀取過程將被阻止,直到寫入過程試圖打開。無論哪種方式,兩者同時開放成功。

在你的程序中,你創建了一個試圖打開寫入的子進程「紅色」,以及一個父進程「綠色」,它也試圖打開寫入。還沒有人閱讀,所以都被封鎖了。將會創建其他2個進程的代碼沒有到達,因爲它是在「綠色」進程中打開並阻止它的。

2

您打開管道進行書寫。這將阻塞,直到管打開閱讀。 由於父母不會分娩更多的孩子,所有這一切都會停止。

我沒有訪問到Unix平臺,所以我沒有嘗試編譯它,但你可以嘗試一些這樣:

// creating the named pipe 
#define CHILD_COUNT 3 
mknod("/tmp/namedpipe", S_IFIFO | 0600, 0); 
const char* childname[CHILD_COUNT] = { "Red", "Blue", "Yellow" }; 
const char* colorname[CHILD_COUNT] = { "RED\n", "BLUE\n", "YELLOW\n" }; 
int myPipe; 

const char* colour; 

pid_t p; 
int i; 
for (i=0; i<CHILD_COUNT; i++) 
{ 
    p = fork(); 
    if (p < 0) { 
    printf("Fork failed\n"); 
    } 
    else if (p == 0) // this is a child, do child stuff 
    { 
    printf("\nPid %d (%s) started\n", getpid(), childname[i]"); 
    myPipe = open("/tmp/namedpipe", O_WRONLY); 
    colour = colorname[i]; // =="RED\n" for first child 
    write(myPipe, colour, strlen(colour) +1); 
    close(myPipe); 
    return; 
    } 
    // else it's the parent, spawn more children 
} 

// Parent 
printf("This is the reader process"); 
myPipe = open("/tmp/namedpipe", O_RDONLY); 
char nextChar; 
while (read(myPipe, &nextChar, 1) == 1) 
    printf("%c", nextChar); 
close(myPipe); 
+0

謝謝,我試着用你的代碼,但是它給出了for循環的錯誤:'error:'for循環初始聲明只允許在C99模式下使用 test.c:24:2:note:use option - std = c99或-std = gnu99來編譯你的代碼'不知道這是什麼意思 – user1985189

+0

因爲'(int i = 0; i someuser

相關問題