簡體   English   中英

Pipe()和fork()

[英]Pipe() and fork()

我的程序的目標是創建兩個管道和兩個進程,以相互交流對管道的讀寫。

  1. 進程p1從管道c1讀取並寫入管道c2
  2. 進程p2從管道c2讀取並寫入管道c1

直到從管道讀取的數目小於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

而且,當然,你是不是檢查的結果值readwrite的意外情況。

問題是p2分叉了2次。 在父進程中一次,在p1進程中第二次。

代替:

  p1 = fork();
  p2 = fork();

您需要這樣寫:

p1 = fork();
if (p1 > 0) {
        p2 = fork();
}

您的代碼不進行正確的錯誤校驗,來電來readwrite ,這意味着,如果有從管道讀出了問題,孩子會進入永無止境的循環為一體的價值c不會到達終止值。

由於子進程完成后會關閉管道,因此您極有可能進入競爭狀態,其中一個進程先關閉管道,然后另一個進程讀取最新的c值。 由於您對fork的調用的位置更加復雜,因為當前您最終擁有3個子進程而不是2個子進程。

您應該將第二個調用移至switch之后的fork ,因為您知道那時您只能在父進程中,而且還將管道的關閉位置移到父進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM