运行 在 C 中使用管道的并发进程

Running concurrent processes using pipe in C

我正在用 C 编写一项任务,旨在使用管道在两个进程之间传递变量。两个进程都必须从父进程派生,并且它们必须 运行 同时传递一个字符(如下所示)。

我遇到的问题是 fork()ed 进程不是同时 运行ning。发送方似乎先行,在 运行ning 约 26 秒后接收方开始。这是我写的代码:

#include <stdio.h>

int ret;
int pipearray[2];
char buffer[26];

void mysender();
void myreceiver();

int main()
{
  int pid = 0;
  int i = 0;
  ret = pipe(pipearray);


  while (i < 2) {
    pid = fork();
    if ( pid == 0 && i == 0 ) /* child process execution (receiver) */
      {
    myreceiver();
    printf("Your receiver is done\n");
    exit(0);
      }

     else if ( pid == 0 && i == 1 ) /* now executes sender */
     {
    mysender();
    printf("Your sender is done\n");
    exit(0);
     }
    ++i;
  }

  close(pipearray[0]);
  close(pipearray[1]);
  sleep(30);
  printf("Parent function has finished.\n");      

  return 0;
}

void mysender() 
{
  char c;
  int index = 90;
  close(pipearray[0]);

  while (index > 64) /* loop for all values of A-Z in ASCII */ 
    {      
      c = (char) index;
      open(pipearray[1]);
      write(pipearray[1], c, sizeof(c)); /* Sends letter to pipe */
      --index;
      sleep(1);
    }

  close(pipearray[1]);
}

void myreceiver()
{
  int index = 0;
  close(pipearray[1]);

  while(buffer != 'A') /*loop runs until 'A' is handled */
  { 
    sleep(1);
    open(pipearray[0]);
    read(pipearray[0], buffer, 1);
    printf("%s", &buffer);
    index++;
    if ( index == 26 ) { break; }
  }

  close(pipearray[0]);
}

预期结果:

ZYXWVUTSRQPONMLKJIHGFEDCBA
Your sender is done
Your receiver is done
The parent function has finished.

我的结果:

Your sender is done
The parent function has finished.
Your receiver is done

我是 C 编程的新手,但我已经为此努力了一段时间。任何关于为什么这些可能不会同时 运行ning 的提示将不胜感激。

您的代码中有很多错误。不要尝试在 fork 之后打开管道,它已经打开并且没有名称。 write应该使用c的地址。读一定要读到正确的地方。写入标准输出后必须进行刷新。您的条件必须稍作修改才能保证正确。父进程必须等待其子进程。这是修改后的代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int ret;
int pipearray[2];
char buffer[26];

void mysender();
void myreceiver();

int main()
{
  int pid = 0;
  int i = 0;
  ret = pipe(pipearray);


  while (i < 2) {
    pid = fork();
    if ( pid == 0 && i == 0 ) /* child process execution (receiver) */
      {
        myreceiver();
        printf("Your receiver is done\n");
        exit(0);
      }

    else if ( pid == 0 && i == 1 ) /* now executes sender */
      {
        mysender();
        printf("Your sender is done\n");
        exit(0);
      }
    ++i;
  }

  close(pipearray[0]);
  close(pipearray[1]);
  // Don't sleep, but wait until the end of the two children
  wait(NULL);
  wait(NULL);
  //  sleep(30);
  printf("Parent function has finished.\n");      

  return 0;
}

void mysender() 
{
  char c;
  int index = 90;
  close(pipearray[0]);

  while (index > 64) /* loop for all values of A-Z in ASCII */ 
    {      
      c = (char) index;
      // try to open a anonymous pipe is a non-sense
      //      open(pipearray[1]);
      // Send a buffer by its address
      write(pipearray[1], &c, sizeof(c)); /* Sends letter to pipe */
      --index;
      sleep(1);
    }

  close(pipearray[1]);
}

void myreceiver()
{
  int index = 0;
  close(pipearray[1]);

  // Ensure condition is entered first
  buffer[index] = 0;
  // This is not the best condition ever, but ok.
  while(buffer[index] != 'A') /*loop runs until 'A' is handled */
  { 
    sleep(1);
    // Don't open an anonymous pipe
    //    open(pipearray[0]);
    // Read at the right position
    read(pipearray[0], buffer+index, 1);
    // print and flush, could also be printf("%s"...); flush(stdout);
    printf("%s\n", buffer);
    index++;
    if ( index == 26 ) { break; }
  }

  close(pipearray[0]);
}

现在,考虑删除 reader 中的睡眠,因为它将 与写入同步,这样如果没有完成写入,就不可能读取. Alos考虑多读一个字节,因为没有message的概念,所以你可以读多少你认为需要读的字节,和往常一样,最好尝试读尽可能多的字节。