C叉和管道打印pid按顺序

时间:2016-12-13 20:11:07

标签: c pipe fork

所以我需要这个程序,它需要使用fork()创建argv [1]子项并打印它们的子项数以及它们创建的PID值。

我必须使用管道阻塞属性来做到这一点。

示例输出:

我是孩子1,我的PID是25853。

我是孩子2,我的PID是25854。

我是孩子3,我的PID是25855。

这是我到目前为止所尝试过的,但它并不尊重儿童创作的顺序。

int main(int argc, char* argv[])
{
    char buffer[80];
    int p[2], i;
    int pid = getpid();
    for (i = 0; i < atoi(argv[1]); i++) {
        pipe(p);
        if (fork() == 0) {
            read(p[0], &pid, sizeof(pid)); // It should block here until there's
            // something in the pipe to read
            sprintf(buffer, "I am child %d and my PID is %d\n", i + 1, getpid());
            write(1, &buffer, strlen(buffer));
            close(p[0]);
            close(p[1]);
            exit(0);
        }
        else { // parent
            close(p[0]);
            write(p[1], &pid, sizeof(pid));
            close(p[1]); // The child is able to read the EOF now.
        }
    }
    while ((waitpid(-1, NULL, 0)) > 0)
        ;
    close(p[0]);
    close(p[1]);
    sprintf(buffer, "I've finished\n");
    write(1, &buffer, strlen(buffer));
}

我觉得我很接近,但我没有正确使用管道阻挡功能。 我需要一些建议,谢谢。

1 个答案:

答案 0 :(得分:1)

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    if (argc != 2) {
        return 1;
    }
    int const n = atoi(argv[1]);
    for (int i = 0; i < n; i++) {
        int p[2];
        if (pipe(p) != 0)
            return 1;
        int pid = fork();
        if (pid == 0) {
            close(p[1]);
            if (read(p[0], &pid, sizeof pid) != sizeof pid)
              return 1;
            close(p[0]);
            fprintf(stdout, "I am child %d and my PID is %d\n", i + 1, pid);
            return 0;
        }
        else if (pid > 0) {
            close(p[0]);
            if (write(p[1], &pid, sizeof pid) != sizeof pid)
              return 1;
            close(p[1]);
            if (waitpid(pid, NULL, 0) == -1)
                return 1;
        }
        else {
            return 1;
        }
    }

    fprintf(stdout, "I've finished\n");
}