Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C、 管道消息到子进程不工作。为什么?_C_Linux_Unix_Centos6 - Fatal编程技术网

C、 管道消息到子进程不工作。为什么?

C、 管道消息到子进程不工作。为什么?,c,linux,unix,centos6,C,Linux,Unix,Centos6,我目前正在为我的操作系统课程做一项作业,我们需要编写一个C程序,首先打开四个管道,然后创建三个子管道 然后,父进程将接收用户发送给子进程的消息,并通过管道将它们发送给子进程。然后,子进程将显示它们收到的所有消息 管道1将从父管道到子管道1。 管道2将从父对象传递到子对象2或3。 管道3和4是连接子级2和3的管道,以确保消息以正确的子级结尾 您的程序应按如下方式运行: • AFTER opening the pipes and creating the children, the parent

我目前正在为我的操作系统课程做一项作业,我们需要编写一个C程序,首先打开四个管道,然后创建三个子管道

然后,父进程将接收用户发送给子进程的消息,并通过管道将它们发送给子进程。然后,子进程将显示它们收到的所有消息

管道1将从父管道到子管道1。 管道2将从父对象传递到子对象2或3。 管道3和4是连接子级2和3的管道,以确保消息以正确的子级结尾

您的程序应按如下方式运行:

•   AFTER opening the pipes and creating the children, the parent process should prompt the user for the number of messages to pass. ONLY the parent should have access to this quantity. The children should not be aware of it!

•   Once the parent knows how many messages to expect from the user, it should prompt the user for those messages in the form:
“<message string> <child to receive message>”

•   You may assume that messages are only one word in length (you do not need to handle spaces in messages).

•   The parent will then use pipes P1 and P2 to send all the messages to the appropriate children.

•   Because C2 and C3 share pipe P2, they may receive each other’s messages. In this situation, they are responsible for using P3 or P4 to forward the messages as appropriate.

•   Each process should ensure that its pipes are unidirectional.

•   Once received, messages MUST be printed out in the form
“Child <x> read message: <msg>”
Where <x> is the number of the child (1, 2, 3) that is printing the message and
<msg> is the message itself.

*Hint: To avoid blocking reads in the children, you should consider what happens when processes close one end of a pipe.

*Hint: When sending messages to C2 and C3, you may want to append a special character to the message so that they will know if it was meant for them or not.

*Hint: It’s probably a good idea to perform all the writes before performing any reads.
•打开管道并创建子进程后,父进程应提示用户要传递的消息数。只有父级才能访问此数量。孩子们不应该意识到这一点!
•一旦家长知道需要从用户处收到多少条消息,应以以下形式提示用户输入这些消息:
“ ”
•您可以假设消息的长度只有一个单词(不需要处理消息中的空格)。
•然后,父级将使用管道P1和P2将所有消息发送给相应的子级。
•由于C2和C3共享管道P2,它们可能会相互接收消息。在这种情况下,他们负责根据需要使用P3或P4转发消息。
•每个过程应确保其管道是单向的。
•收到信息后,必须以表格形式打印出来
“儿童阅读邮件:”
其中是正在打印消息的子项(1、2、3)的编号,以及
这就是信息本身。
*提示:为了避免在孩子中阻塞读取,你应该考虑当进程关闭管道的一端时会发生什么。
*提示:在向C2和C3发送消息时,您可能希望在消息中附加一个特殊字符,以便他们知道消息是否针对他们。
*提示:在执行任何读取之前,最好先执行所有写入操作。
当前,“我的孩子”进程将接收一到两条消息,但随后将停止。我认为read函数是阻塞的,但我不确定是为了什么,或者为什么

样本输出:

[root@cmachineCIS370]#/parksPipes有多少条消息?三,

信息(1):ey 1

信息(2):第1天

信息(3):yo 1

消息:ey已写入子1

消息:ay已写入子1

信息:你写信给孩子1

父项正在退出

C1接收:ey

(此时程序挂起。)

代码:

#包括
#包括
#包括
#包括
#包括
#定义msgsize256
main()
{
int ppid=getpid();//获取父id
int n消息=0;
int p1[2];int p2[2];int p3[2];int p4[2];//用于管道的数组
如果(管道(p1)=-1){printf(“p1错误,错误号:%d”,错误号);退出(-1);}如果(管道(p2)=-1){printf(“p2错误,错误号:%d,错误号”);退出(-1);}//打开管道
如果(管道(p3)=-1){printf(“p3错误,错误号:%d”,错误号);退出(-1);}如果(管道(p4)=-1){printf(“p4错误,错误号:%d,错误号”);退出(-1);}
int kidpid1=fork();
if(kidpid1==0)//子1
{
国际nread;
char-mesg[MSGSIZE];
关闭(p1[1]);
关闭(p2[0]);关闭(p2[1]);关闭(p3[0]);关闭(p3[1]);关闭(p4[0]);关闭(p4[1]);
而((nread=read(p1[0],mesg,MSGSIZE))>0)//读取将被阻止,直到管道的写入端关闭
{
printf(“C1接收:%s\n”,mesg);
}
printf(“子1退出…\n”);
出口(0);
}
如果(kidpid1>0)//父
{
int kidpid2=fork();
if(kidpid2==0)//子2
{
国际nread;
char-mesg[MSGSIZE];
而((nread=read(p2[0],mesg,MSGSIZE))>0)
{
printf(“指挥与控制接收:%s\n”,mesg);
}
printf(“儿童2退出…\n”);
出口(0);
}
else如果(kidpid2>0)//父
{
int kidpid3=fork();
if(kidpid3==0)//子3
{
关闭(p2[1]);
国际nread;
char-mesg[MSGSIZE];
而((nread=read(p2[0],mesg,MSGSIZE))>0)
{
printf(“C3接收:%s\n”,mesg);
}
printf(“儿童3退出…\n”);
出口(0);
}
如果(kidpid3>0)//父
{
close(p1[0]);close(p2[0]);close(p3[0]);close(p4[0]);//关闭管道的所有读取端(父管道将不会读取)
close(p3[1]);close(p4[1]);//关闭管道3和4的写入端(父级不会写入这些管道)
printf(“有多少条消息?”);
scanf(“%d”和&n消息);
char*msg[n消息];
int child[n消息];
int i=0;
对于(i=0;i您在代码中有未定义的行为。您有一个指向字符
msg
的指针数组,您在读取用户输入时使用此数组

这里的第一个问题是数组中的指针未初始化。未初始化的局部变量的值是不确定的,以除初始化之外的任何方式使用它们都会导致未定义的行为。可以为这些指针动态分配内存,也可以使用字符数组数组,例如

char msg[nmessages][MAX_MESSAGE_LENGTH];
第二个问题是如何在
scanf
调用中使用数组
msg
你得到一个指向指针的指针,也就是说,你得到一个
字符**
,这与我想的不完全一样?如果你将
msg
更改为一个数组,这个问题会自行解决,但也可以通过删除操作符的地址并传递
m来解决
char msg[nmessages][MAX_MESSAGE_LENGTH];