2013-05-20 3 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 й по другому, я получил:

message 1 
the second messagea third message for the third process 

(Это на MacBook Pro с процессором Intel Core i7, работающий Mac OS X 10.8.3, и с помощью GCC 4.7.1.)

+0

я забыл упомянуть. Я попытался дважды использовать инструкцию read и дважды печатать. Он печатает первую строку два раза, а не обе строки. – Matador89

+0

Отредактировано это, чтобы включить это. – Matador89

+0

Поскольку вы не обращаете внимания на возвращаемое значение из 'read()', никто не может догадаться, что вы возвращаете. Даже если вы игнорируете ошибки записи, вы должны обратить внимание на то, что возвращает 'read()'; вы не знаете, сколько данных действительно, если вы не посмотрите на количество возвращенных байтов. –

Смежные вопросы