在 C 中使用管道运行并发进程
Posted
技术标签:
【中文标题】在 C 中使用管道运行并发进程【英文标题】:Running concurrent processes using pipe in C 【发布时间】:2015-10-27 05:55:23 【问题描述】:我正在使用 C 语言进行赋值,旨在使用管道在两个进程之间传递变量。两个进程都必须从父进程派生,并且它们必须同时运行才能一次传递一个字符(如下所示)。
我遇到的问题是 fork()ed 进程没有同时运行。发送者似乎先走,运行约 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 编程非常陌生,但我已经为此努力了一段时间。任何关于为什么这些可能不会同时运行的提示将不胜感激。
【问题讨论】:
open(pipearray[1])
到底应该做什么?
这不是 C 编程。它是 POSIX(或 Unix)编程。 C99 或 C11 标准 dpnt 知道 fork
和 pipe
。您应该仔细阅读 RTFM fork(2)、pipe(2)、open(2) 并阅读 ALP
Protip:总是用-Wall -Wextra -Werror
编译。
【参考方案1】:
您的代码中有很多错误。不要尝试在fork之后打开管道,它已经打开并且没有名称。写应该使用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]);
现在,考虑移除读取器中的休眠,因为它将与写入同步,这样如果没有写入,就不可能读取。 Alos 考虑多读一个字节,因为没有message的概念,这样你就可以读到你认为需要读多少字节,和往常一样最好尝试读一堆尽可能字节。
【讨论】:
这非常有帮助。谢谢。以上是关于在 C 中使用管道运行并发进程的主要内容,如果未能解决你的问题,请参考以下文章