我正在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编程很陌生,但我已经暂时搁置了一段时间。任何有关这些可能无法同时运行的提示都将非常感激。
答案 0 :(得分:2)
您的代码中存在许多错误。不要尝试在fork之后打开管道,它已经打开并且没有名称。写应该使用c的地址。阅读必须读到正确的地方。写入stdout后必须刷新。您的条件必须稍加修改才能保证正确。父进程必须等待其子进程。这是修改后的代码:
#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 的概念,因此您可以读取您认为需要读取的字节数,并且像往常一样最好尝试读取一堆你可以使用字节。