c - 使用管道的IPC机制来完成程序,以便子进程和父进程打印相同的输出

标签 c pipe fork

所以我最近参加了一个关于操作系统的类(class)的考试,它要求我使用 pipeline() 编写一个程序。该程序旨在通过管道发送和接收数据,以便无论运行哪个文件,输出都是相同的。

输出应如下所示。

Hello (from child) 1

Hello (from parent)

Hello (from child) 2

模板代码如下。 (我无法更改此代码,我只是插入代码以使其工作)。没有创造力...我知道。

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>

int main() {
    pid_t pid;
    char buf[32];



    if ((pid = fork()) < 0) {
        puts("Error");
    } else if(pid == 0) { //child


        fprintf(stdout, "Hello (from child) 1\n");



        fprintf(stdout, "Hello (from child) 2\n");

        fflush(stdout);

    }
    else {


        fprintf(stdout, "Hello (from parent)\n");


    }
}

过了一段时间,我的结论如下。但执行后没有任何打印。 (我无法测试它,因为这是纸质考试,但我后来测试了它)。另外,我的时间很紧迫,所以我知道错误可能很频繁。

我添加了用户开始用户结束来显示我可以在哪里更改代码。任何帮助将不胜感激。

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>

int main() {
    pid_t pid;
    char buf[32];

    // User Start
    int fds[2];
    pipe(fds);
    close(1);
    dup(fds[1]);
    // User End

    if ((pid = fork()) < 0) {
        puts("Error");
    } else if(pid == 0) { //child

        // User Start

        // User End
        fprintf(stdout, "Hello (from child) 1\n");

        // User Start
        write(fds[1],"Hello (from child) 1\n",21);
        read(fds[0],buf,21);
        write(fds[1],"Hello (from child) 2\n",21);
        // User End

        fprintf(stdout, "Hello (from child) 2\n");
        // User Start

        // User End

    }
    else {
        // User Start
        read(fds[0],buf,21);
        // User End

        fprintf(stdout, "Hello (from parent)\n");
        // User Start
        write(fds[1],"Hello (from parent)\n",21);
        read(fds[0],buf,21);

        // User End

    }
}

UPDATE

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>


int main()
{
    pid_t pid;
    char buf[32];
    int returnstatus1;
    int fds[2];
    
    returnstatus1 = pipe(fds);
    printf("Return status = %d\n",returnstatus1);  //check if pipe is created or not

    if(returnstatus1 == -1)
  {
    printf("Pipe 1 could not be created\n");
    return 1;
  }

    if((pid = fork()) < 0)
    {
        puts("ERROR");
    }
    //child
    else if(pid == 0)
    {

        fprintf(stdout,"hello (from child) 1\n");
        close(fds[0]);
        write(fds[1],"hello  (from child) 1\n",21);
        close(fds[1]);
        read(fds[0],buf,21);
        fprintf(stdout,"hello (from child) 2\n");
        close(fds[0]);
        write(fds[1],"hello  (from child) 2",21);
    }
    //parent
    else
    {
        close(fds[1]);
        read(fds[0],buf,21);
        fprintf(stdout,"hello (from parent)\n");
        close(fds[0]);
        write(fds[1],"hello (from parent)\n",21);
        close(fds[1]);
        read(fds[0],buf,21);
    }
    
    return 0;
}

最佳答案

使用管道进行同步有点不正统,但它是完全可行的。您必须记住,从空管道中读取数据是阻塞的——它会等待,直到有数据写入其中。

因为这样更清楚,我将首先显示父级,而不是子级。当然,if 分支的放置顺序并不重要 - 您可以根据考试的格式进行调整,我强烈建议您这样做,以便掌握窍门。

考虑到这一点,我们继续:

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

int main (void) {
  pid_t pid;
  char buf;
  int parent_pipes[2];
  int child_pipes[2];
  pipe(child_pipes);
  pipe(parent_pipes);
  if ((pid = fork()) < 0)
      puts("Error");
  else if (pid) {
    // parent first!
    // wait for the child to write something into the pipe...
    read(*child_pipes, &buf, 1);
    // and now write to stdout, and tell the child that we're ready
    fprintf(stdout, "Hello (from parent)\n");
    fflush(stdout);
    write(parent_pipes[1], "R", 1); // it doesn't matter what we write; we have to write anything
  } else {
    // and now the child
    // output and flush...
    fprintf(stdout, "Hello (from child) 1\n");
    fflush(stdout);
    // ...and tell the parent that we're ready
    write(child_pipes[1], "R", 1); // write end of the pipe
    // now wait!
    read(*parent_pipes, &buf, 1); // read end of the pipe
    fprintf(stdout, "Hello (from child) 2\n");
  }
  return 0;
}

关于c - 使用管道的IPC机制来完成程序,以便子进程和父进程打印相同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55292045/

相关文章:

C - struct* 在运行时强制转换?

c++ - 关于缺少 header 的编译错误

c++ - FFmpeg - 通过管道提供原始帧 - FFmpeg 不检测管道关闭

C 子进程运行其代码两次

linux - Docker应用在线升级

c - 将 strcmp 与二维数组一起使用

c - 使用 while 循环添加矩阵

c - C中多个管道的实现

c - 使用管道在两个进程之间连续传递数据

C从管道读取所有数据