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 
        }
    } 
}
4

1 回答 1

3

在没有更多数据要读取之前,您的代码不会一直循环。它只读取一次。它也不检查返回的值read(),但它应该检查。

我已经将fork()and 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

另一方面,我得到:

message 1
the second messagea third message for the third process

(这是在配备 Intel Core i7、运行 Mac OS X 10.8.3 并使用 GCC 4.7.1 的 MacBook Pro 上。)

于 2013-05-20T04:25:16.900 回答