2013-05-20 30 views
0

我需要創建三個子進程,每個子進程都從命令行參數中讀取一個字符串,並將字符串寫入單個管道。父母會從管道中讀取字符串,並將其全部三個顯示在屏幕上。我試圖做兩個進程來測試,它打印兩個字符串中的一個,而不是兩個。使用單個管道創建多個子進程

#include <stdio.h> 
#include <unistd.h> 

int main (int argc, char *argv[]) { 

    char *character1 = argv[1]; 
    char *character2 = argv[2]; 

    char inbuf[100]; //creating an array with a max size of 100 

    int p[2]; // Pipe descriptor array 
    pid_t pid1; // defining pid1 of type pid_t 
    pid_t pid2; // defining pid2 of type pid_t 

    if (pipe(p) == -1) { 
     fprintf(stderr, "Pipe Failed"); // pipe fail 
    } 

    pid1 = fork(); // fork 

    if (pid1 < 0) { 
     fprintf(stderr, "Fork Failed"); // fork fail 
    } 

    else if (pid1 == 0){ // if child process 1 
     close(p[0]); // close the read end 
     write(p[1], character1, sizeof(&inbuf[0])); // write character 1 to the pipe 
    } 

    else { // if parent, create a second child process, child process 2 
     pid2 = fork(); 

     if (pid2 < 0) { 
     fprintf(stderr, "Fork Failed"); // fork fail 
     } 

     if (pid2 = 0) { // if child process 2 
      close(p[0]); // close the read end 
      write(p[1], character2, sizeof(&inbuf[0])); // write character 2 to the pipe 
     } 

     else { // if parent process 
      close(p[1]); // close the write end 

      read(p[0], inbuf, sizeof(&inbuf[0])); // Read the pipe that both children write to 
      printf("%s\n", inbuf); // print 

      read(p[0], inbuf, sizeof(&inbuf[0])); // Read the pipe that both children write to 
      printf("%s\n", inbuf); // print 
     } 
    } 
} 

回答

2

在沒有更多數據要讀取之前,您的代碼不會循環。它只讀一次。它也不檢查read()返回的值,但它應該。

我已經將fork()write()(和錯誤檢查)代碼抽象爲函數。這似乎工作:使用命令行

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

static void child(int fd, const char *string) 
{ 
    pid_t pid = fork(); 
    int len = strlen(string); 
    if (pid < 0) 
    { 
     fprintf(stderr, "%.5d: failed to fork (%d: %s)\n", 
       (int)getpid(), errno, strerror(errno)); 
     exit(1); 
    } 
    else if (pid > 0) 
     return; 
    else if (write(fd, string, len) != len) 
    { 
     fprintf(stderr, "%.5d: failed to write on pipe %d (%d: %s)\n", 
       (int)getpid(), fd, errno, strerror(errno)); 
     exit(1); 
    } 
    else 
     exit(0); 
} 

int main (int argc, char *argv[]) 
{ 
    char inbuf[100]; //creating an array with a max size of 100 
    int p[2]; // Pipe descriptor array 

    if (argc != 4) 
    { 
     fprintf(stderr, "Usage: %s str1 str2 str3\n", argv[0]); 
     return 1; 
    } 

    if (pipe(p) == -1) 
    { 
     fprintf(stderr, "Pipe Failed"); // pipe fail 
     return 1; 
    } 

    for (int i = 0; i < 3; i++) 
     child(p[1], argv[i+1]); 

    int nbytes; 
    close(p[1]); // close the write end 
    while ((nbytes = read(p[0], inbuf, sizeof(inbuf))) > 0) 
     printf("%.*s\n", nbytes, inbuf); // print 

    return 0; 
} 

我的命令多次跑,每次:

./p3 'message 1' 'the second message' 'a third message for the third process' 

在一個運行,輸出爲:

the second messagemessage 1 
a third message for the third process 

在另一,我得到了:

the second messagemessage 1a third message for the third process 

A ND另一個,我得到:

message 1 
the second messagea third message for the third process 

(這是在MacBook Pro上採用Intel酷睿i7,運行Mac OS X 10.8.3,並使用GCC 4.7.1。)

+0

我忘了提。我嘗試使用read語句兩次並打印兩次。它打印第一個字符串兩次,而不是兩個字符串。 – Matador89

+0

編輯它包括。 – Matador89

+0

既然你不關注'read()'的返回值,那麼沒有人能猜到你回來的東西。即使您忽略寫入錯誤,您也必須注意'read()'返回的內容;除非查看返回的字節數,否則您不知道有多少數據是有效的。 –