在UNIX中创建FIFO

时间:2014-03-18 18:35:21

标签: c unix pipe fifo

我正在尝试编写简单的FIFO程序,其中包含三个子程序,它们将值发送到文件,父程序读取它。我的问题是cfp = fopen(fifoName,“w”);应该earse文件并保存新值,所以我认为输出应该看起来像“这是父。从fifo上的孩子收到的值30”但我的输出是“这是父。从fifo的孩子那里获得2010年的价值“。感谢您的帮助。

我的代码有什么问题?

int main()
{
  int ret;
  int p1, p2, p3, p4;
  int value;
  char fifoName[] = "/tmp/testfifo20";
  char errMsg[1000];
  FILE *cfp;
  FILE *pfp;
  int x1;
  int x2, x3, x4;

  ret = mknod(fifoName, S_IFIFO | 0600, 0);
  if (ret < 0)
  {
    sprintf(errMsg, "Unable to create fifo: %s", fifoName);
    errexit(errMsg);
  }

  if ((p3 = fork()) == 0)
  {
    x1 = 10;
    cfp = fopen(fifoName, "w");
    if (cfp == NULL)
      errexit("Unable to open fifo for writing");
    ret = fprintf(cfp, "%d", x1);
    fflush(cfp);
    exit(0);
  }

  if ((p2 = fork()) == 0)
  {
    x2 = 20;
    cfp = fopen(fifoName, "w");
    if (cfp == NULL)
      errexit("Unable to open fifo for writing");
    ret = fprintf(cfp, "%d", x2);
    fflush(cfp);
    exit(0);
  }

  if ((p3 = fork()) == 0)
  {
    x3 = 30;
    cfp = fopen(fifoName, "w");
    if (cfp == NULL)
      errexit("Unable to open fifo for writing");
    ret = fprintf(cfp, "%d", x3);
    fflush(cfp);
    exit(0);
  }
  else
  {
    pfp = fopen(fifoName, "r");
    if (pfp == NULL)
      errexit("Unable to open fifo for reading");
    ret = fscanf(pfp, "%d", &value);
    if (ret < 0)
      errexit("Error reading from named pipe");
    fclose(pfp);
    printf("This is the parent. Received value %d from child on fifo \n",
        value);
    unlink(fifoName);
    exit(0);
  }
}

1 个答案:

答案 0 :(得分:0)

为什么期望30?您应该期望102030的任意组合,例如1020303020202010。< / p>

2010是一个非常合理的结果。你分叉3个孩子。实际上,在第一个分叉处有一个拼写错误,因为您将其PID存储到p3而不是p1。但这没关系。

重要的是,父流程及其3个孩子的安排不在您手中。显然,内核按以下顺序安排了您的进程:

  • p2:将20写入FIFO
  • p1:将10写入FIFO,其中包含2010现在
  • parent:从FIFO中读取2010,现在为空
  • p3:将30写入FIFO,其中包含30现在

但是父进程只读取FIFO一次,因此错过了30