c - "Ping pong"使用 unix 进程和管道的游戏

标签 c unix process pipe

有人可以帮我解决这个问题吗?

我在下面写下了完整的问题。

乒乓球。两个进程将玩乒乓球游戏。 第一个进程将生成一个介于 5000 和 15000 之间的随机数,并将其发送到另一个进程。 此过程将减去一个随机值(50 到 1000 之间)并将该数字发回, 进程之间的聊天将使用管道 channel 来实现。 当值低于零时游戏结束。 每个进程都会打印接收到的值。

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

int main ()
{

  int  p2c[2], c2p[2], number, n;

  pipe(p2c);    //parent to child pipe
  pipe(c2p);    //child to parent pipe

  number = rand() %10000 + 5000;
  printf("Generated number: %d\n", number);

  if (fork () == 0 ) 
  { //child process
      while(number > 0)
      {
         printf("in child process\n");
         read(p2c[0], &number, sizeof(int));
         printf("(F).received number: %d\n", number);
         n = rand() %1000 + 50;
         number = number - n;
         write(c2p[1], &number, sizeof(int));
       } 
      close(p2c[0]); close(p2c[1]);
      close(c2p[0]); close(c2p[1]);
      exit(0);

  } else {
    while(number > 0) 
    {
      printf("in parent process\n");
      read(c2p[0], &number, sizeof(int));
      printf("(P).received number: %d\n", number);
      number = number - n;
      write(p2c[1], &number, sizeof(int));
    }
   close(p2c[0]); close(p2c[1]);
   close(c2p[0]); close(c2p[1]);
   wait();
 }
printf ("The final number is: %d\n", number);
}

它不起作用,我不明白为什么。它打印的所有内容是:

Generated number: (a random number...)
in parent process
in child process

我也不明白为什么它首先进入父进程而不进入子进程。有人可以帮我解决这个问题吗?

最佳答案

首先,没有fork进程的顺序。 child 和 parent 或多或少同时执行,尽管事实上 child 在源代码中比 parent 更高。在这里, parent 碰巧比 child 快一点地拍打标准输出。

您遇到的主要问题是死锁。 parent 正在等待 child 说些什么 (read(c2p[0]...)); child 正在等待 parent 打破沉默 (read(p2c[0], ...))。他们中的一个必须先说些什么,否则他们会在他们搬家之前就老死。

通过告诉另一个初始状态,让其中一个在循环之前开始交谈。然后它应该会在以后正常工作,因为他们在说和听之间交替。

关于c - "Ping pong"使用 unix 进程和管道的游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29889318/

相关文章:

linux - 如何在没有 ssh 的情况下在远程计算机(linux)上执行进程?

c# - 如果某个进程在没有计时器的情况下运行,请执行某些操作

c - 如何使用 linux 内核中的 lockdep 功能进行死锁检测

excel - 如何通过 VBA 识别 UNIX 文本文件中的隐藏回车符?

c - srand(getpid()) 会影响格式/结构吗?

linux - Linux 中登录的唯一用户列表

c# - 如何在新实例中加载 MS Word 文件?

java - 与java相比,c中的openssl摘要不同

c++ - 二进制 + 的无效操作数

c - gcc 无法在 Mac 上运行