C 为什么父进程只从子进程读取第一条和第六条消息?
我正在尝试从子进程向父进程发送十条消息。但是程序的输出显示父进程只读取第一条和第六条消息。我尝试更改代码中sleep()的位置,也尝试使用while()来读取而不是for(),但问题仍然是一样的。 代码如下:C 为什么父进程只从子进程读取第一条和第六条消息?,c,process,fork,parent-child,C,Process,Fork,Parent Child,我正在尝试从子进程向父进程发送十条消息。但是程序的输出显示父进程只读取第一条和第六条消息。我尝试更改代码中sleep()的位置,也尝试使用while()来读取而不是for(),但问题仍然是一样的。 代码如下: int main(int argc, char *argv[]){ char ch, message_from_A[100], message_from_B[100], msg_to_log[100], msg_to_B[100]; int i, x, fd_log[2], fd_A_B
int main(int argc, char *argv[]){
char ch, message_from_A[100], message_from_B[100], msg_to_log[100], msg_to_B[100];
int i, x, fd_log[2], fd_A_B[2], fd_B_C[2], fd_B_D[2];
pipe(fd_log);
//fork process A
if (fork()==0) { //child
printf("Inside process A\n");
for (i=0; i < 10; i++) {
//creat new msg
x = (rand() % 2);
if (x == 1)
ch='C';
else
ch='D';
//write msg to log pipe
sprintf(msg_to_log, "A sent to B: %c %d\n", ch, i);
printf("wirtten to log pipe--> %s\n", msg_to_log);
close(fd_log[READ]);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
}//end for()
close(fd_log[WRITE]); //this line won't affect output
_exit(1);
} else { //parent
printf("Inside process log\n");
close(fd_log[WRITE]);
while ( read(fd_log[READ], message_from_A, 100) > 0 ) {
sleep(1);
printf("\nmsg from A: %s", message_from_A);
}
close(fd_log[READ]); //this line won't affect output
}}
intmain(intargc,char*argv[]){
char ch、消息_from_A[100]、消息_from_B[100]、消息_to_log[100]、消息_to_B[100];
int i,x,fd_log[2],fd_A_B[2],fd_B_C[2],fd_B_D[2];
管道(fd_日志);
//分叉过程A
如果(fork()==0){//child
printf(“内部进程A\n”);
对于(i=0;i<10;i++){
//创造新的味精
x=(rand()%2);
如果(x==1)
ch='C';
其他的
"D",;
//将消息写入日志管道
sprintf(消息发送到日志,“A发送到B:%c%d\n”,ch,i);
printf(“wirtten-to-log管道-->%s\n”,msg\u-to\u-log);
关闭(fd_日志[读取]);
写入(fd_log[write],msg_to_log,strlen(msg_to_log)+1);
}//结束()
关闭(fd_log[WRITE]);//此行不会影响输出
_出口(1);
}else{//parent
printf(“内部过程日志”);
关闭(fd_日志[写入]);
while(读取(fd_日志[read],来自_A的消息,100)>0){
睡眠(1);
printf(“\nmsg来自A:%s”,消息来自A);
}
关闭(fd_log[READ]);//此行不会影响输出
}}
此程序的输出显示父级仅读取第一条和第六条消息!这是输出:
内部进程日志
内部进程A
wirtten到日志管道-->A发送到B:C 0
Wirten到日志管道-->A发送到B:C 1
Wirten到日志管道-->A发送到B:C 2
Wirten到日志管道-->A发送到B:D 3
Wirten到日志管道-->A发送到B:D 4
Wirten到日志管道-->A发送到B:D 5
Wirten到日志管道-->A发送到B:D 6
Wirten到日志管道-->A发送到B:D 7
Wirten到日志管道-->A发送到B:C 8
Wirten到日志管道-->A发送到B:C 9
消息从A:A发送到B:C 0
味精来自A:B:D 5
我很感激任何想法或建议 这里的罪魁祸首似乎是这样的:
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
这应该是:
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log));
否则您将发送一个额外的字符(将是'\0'
,msg\u to\u log
为全局字符)。。因此,即使read()
成功,它也不会打印整个字符序列(只有在'\0'
之前)。在每次填充之前,也要将memset
msg_to_log
(确保没有旧字符挂在那里)。此外,每次打印后(出于相同的原因),还会收到来自A的memset
消息
另外,移动close(fd_log[READ])代码>在for循环之前 这里的罪魁祸首似乎是这样的:
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
这应该是:
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log));
否则您将发送一个额外的字符(将是'\0'
,msg\u to\u log
为全局字符)。。因此,即使read()
成功,它也不会打印整个字符序列(只有在'\0'
之前)。在每次填充之前,也要将memset
msg_to_log
(确保没有旧字符挂在那里)。此外,每次打印后(出于相同的原因),还会收到来自A的memset
消息
另外,移动close(fd_log[READ])代码>在for循环之前 在子对象中,您正在写入多个数据块,这些数据块看起来像:
A sent to B: C x
每个后面都跟一个空字符(上面的“x”被一个数字替换,该数字表示写入管道的数据行)。但是,读取管道的进程将读取放入管道中的任何内容,直到read()
函数调用中指定的限制-它不会在空字符处停止。因此,第一个read()
可能会从管道中的以下内容中获取前100个字符:
A sent to B: C 0\0A sent to B: C 1\0A sent to B: C 2\0A sent to B: C 3\0A sent to B: C 4\0A sent to B: C 5\0
但是,当父级显示从管道读取的内容时,它会将其打印为以null结尾的字符串,因此只显示缓冲区的第一部分
然后,下一次读取将拾取留在管道中的片段(以及该片段之后的任何内容),并再次仅显示到空字符为止
要解决此问题,请使用read()
中的返回代码来找出返回的内容,并适当地处理空字符。在子级中,您正在写入几个类似以下内容的数据块:
A sent to B: C x
每个后面都跟一个空字符(上面的“x”被一个数字替换,该数字表示写入管道的数据行)。但是,读取管道的进程将读取放入管道中的任何内容,直到read()
函数调用中指定的限制-它不会在空字符处停止。因此,第一个read()
可能会从管道中的以下内容中获取前100个字符:
A sent to B: C 0\0A sent to B: C 1\0A sent to B: C 2\0A sent to B: C 3\0A sent to B: C 4\0A sent to B: C 5\0
但是,当父级显示从管道读取的内容时,它会将其打印为以null结尾的字符串,因此只显示缓冲区的第一部分
然后,下一次读取将拾取留在管道中的片段(以及该片段之后的任何内容),并再次仅显示到空字符为止
要解决此问题,请使用read()
中的返回代码来确定返回的内容,并适当处理空字符