[英]Pipe() and fork()
我的程序的目標是創建兩個管道和兩個進程,以相互交流對管道的讀寫。
直到從管道讀取的數目小於BIG_INT_STOP,兩個過程才繼續增加管道中的數目。 此條件成立后,首先進行讀取,關閉管道,退出並打印數字。 問題是:當進程p2在p1之前結束時,它起作用;而當進程p1在p2之前結束時,它進入循環。 你能解釋一下為什么嗎?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include <sys/wait.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#define BIG_INT_STOP 40
#define TEST_ERROR if (errno) {fprintf(stderr, \
"%s:%d: PID=%5d: Error %d (%s)\n", \
__FILE__, \
__LINE__, \
getpid(), \
errno, \
strerror(errno));}
int main(){
int c1[2], c2[2], p1, p2, z;
long a = 0, c;
pipe(c1);
pipe(c2);
write(c1[1], &a, sizeof(a));
write(c2[1], &a, sizeof(a));
p1 = fork();
p2 = fork();
switch(p1){
case -1:
TEST_ERROR;
exit(EXIT_FAILURE);
case 0:
read(c1[0], &c, sizeof(c));
while(c != BIG_INT_STOP){
++c;
write(c2[1], &c, sizeof(c));
read(c1[0], &c, sizeof(c));
}
close(c1[0]);
close(c1[1]);
close(c2[0]);
close(c2[1]);
printf("p1: %ld\n", c);
exit(0);
}
switch(p2){
case -1:
TEST_ERROR;
exit(EXIT_FAILURE);
case 0:
read(c2[0], &c, sizeof(c));
while(c != BIG_INT_STOP){
++c;
write(c1[1], &c, sizeof(c));
read(c2[0], &c, sizeof(c));
}
close(c1[0]);
close(c1[1]);
close(c2[0]);
close(c2[1]);
printf("p2: %ld\n", c);
exit(0);
}
while(wait(&z) != -1);
}
您的程序有點奇怪。 主要問題似乎是第二個fork在主程序和第一個孩子中都被執行。 實際上,您正在運行四個過程:main,main的兩個兒子和長子的兒子。 這可能不是您想要的。 您可能想將第一個switch
放在第一個fork
之后,而僅在主程序中執行第二個fork
。
而且,當然,你是不是檢查的結果值read
和write
的意外情況。
問題是p2分叉了2次。 在父進程中一次,在p1進程中第二次。
代替:
p1 = fork();
p2 = fork();
您需要這樣寫:
p1 = fork();
if (p1 > 0) {
p2 = fork();
}
您的代碼不進行正確的錯誤校驗,來電來read
和write
,這意味着,如果有從管道讀出了問題,孩子會進入永無止境的循環為一體的價值c
不會到達終止值。
由於子進程完成后會關閉管道,因此您極有可能進入競爭狀態,其中一個進程先關閉管道,然后另一個進程讀取最新的c
值。 由於您對fork
的調用的位置更加復雜,因為當前您最終擁有3個子進程而不是2個子進程。
您應該將第二個調用移至switch
之后的fork
,因為您知道那時您只能在父進程中,而且還將管道的關閉位置移到父進程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.