繁体   English   中英

为什么父进程仅读取子进程的第一条消息和第六条消息?

[英]Why the parent process read only the first and sixth message from a child process?

我正在尝试从子进程向父进程发送十条消息。 但是程序的输出显示父进程仅读取第一条消息和第六条消息。 我试图更改代码中的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[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
}}

该程序的输出显示父级仅读取第一条消息和第六条消息! 这是输出:

内部流程日志

内部流程A

要记录管道-> A发送到B:C 0

要记录管道-> A发送到B:C 1

要记录管道-> A发送到B:C 2

要记录管道-> A发送到B:D 3

想要记录管道-> A发送到B:D 4

要记录管道-> A发送到B:D 5

要记录管道-> A发送到B:D 6

要记录管道-> A发送到B:D 7

要记录管道-> A发送到B:C 8

要记录管道-> A发送到B:C 9

消息从A:A发送到B:C 0

来自A的消息:B:D 5

我感谢任何想法或建议。

在孩子中,您正在编写一些类似于以下内容的数据块:

A sent to B: C x

每个后跟一个空字符(上面的“ x”由表示写入管道的数据行的数字代替)。 但是,正在读取管道的进程将读取已放入管道的所有内容,直到read()函数调用中指定的限制-它不会在null字符处停止。 因此,第一个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

但是,当父项显示从管道读取的内容时,它会将其打印为以空终止的字符串,因此仅显示缓冲区的第一部分。

然后,下一次读取将拾取保留在管道中的片段(以及该片段之后的所有内容),并再次显示仅直到空字符为止。

要解决此问题,请使用read()的返回码找出返回的内容,并适当处理空字符。

罪魁祸首似乎是这条线:

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_to_log为全局msg_to_log 。)因此,即使read()成功,它也不会打印整个字符序列(只打印'\\0' ) 。 此外memset msg_to_log每次在填充它之前(以确保没有旧的字符挂在那里)。 还要在每次打印后memset message_from_A (出于相同的原因)。

另外,移动close(fd_log[READ]); 在for循环之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM