C按顺序进行叉管打印pid

C按顺序进行叉管打印pid,c,pipe,fork,C,Pipe,Fork,所以我需要这个程序,它需要使用fork()创建argv[1]child,并按创建顺序打印它们的子编号和PID 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) {

所以我需要这个程序,它需要使用fork()创建argv[1]child,并按创建顺序打印它们的子编号和PID

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,我的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));
}
intmain(intargc,char*argv[])
{
字符缓冲区[80];
int p[2],i;
int pid=getpid();
对于(i=0;i0)
;
接近(p[0]);
关闭(p[1]);
sprintf(缓冲区,“我已经完成了”\n);
写入(1,&buffer,strlen(buffer));
}
我觉得我很接近,但我没有正确使用管道阻塞poperties。 我需要一些建议,谢谢。

#包括
#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");
}
#包括 #包括 #包括 #包括 int main(int argc,char*argv[]) { 如果(argc!=2){ 返回1; } int const n=atoi(argv[1]); 对于(int i=0;i0){ 接近(p[0]); if(写入(p[1],&pid,sizeof pid)!=sizeof pid) 返回1; 关闭(p[1]); if(waitpid(pid,NULL,0)=-1) 返回1; } 否则{ 返回1; } } fprintf(stdout,“我已经完成了”\n); }
子级与父级同时运行。特别是,您的父母不会等到孩子完成后才开始下一个孩子,因此孩子打印到控制台的顺序是不确定的。您应该在父循环中的
for()
-循环内
wait()
。是的,关键是它应该是并发的,但您必须使用pipes blockin属性按顺序打印子循环。@EOF所以我不能在每个循环上使用wait,否则它将不会是并发的。“并发”和“必须按特定顺序发生”是不兼容的需求。让你这么做的人不知道他们在做什么。如果您只是不想等待(),您可以创建第二个管道(),父管道从中读取(),子管道关闭,从而解除父管道的阻塞。注意这种情况下的自死锁。@EOF,但这不会是并发的。这是我在大学操作系统课上做的一个练习。从管道中读取数据时,应将孩子阻塞,直到其到达EOF。我不能使用该属性按顺序打印它们吗?