管道中父进程的wait()有什么问题

有人问我:

  1. 下一个代码中有什么问题?
  2. 如何在儿子的过程代码中对其进行修复:
#define BUF_SIZE 4096
int my_pipe[2];
pipe(my_pipe);
char buf[BUF_SIZE];
int status = fork();

//Filled buf with message...
if (status == 0) {  /* son process */
    close(my_pipe[0]);
    write(my_pipe[1],buf,BUF_SIZE*sizeof(char));
    exit(0);
 }
 else {    /* father process */
    close(my_pipe[1]);
    wait(&status);  /* wait until son process finishes */
    read(my_pipe[0],BUF_SIZE*sizeof(char));
    printf("Got from pipe: %s\n",father_buff);
    exit(0);
 }
}

所以我想出了下一个代码来尝试解决该问题:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

#define BUF_SIZE 6

int main() {
    int my_pipe[2];
    pipe(my_pipe);

    char buf[BUF_SIZE];
    int status = fork();
    //Filled buf with message...
    for (int i = 0; i < BUF_SIZE; i++) buf[i] = 'a';

    if (status == 0) {    /* son process */
        close(my_pipe[0]);
        write(my_pipe[1],BUF_SIZE * sizeof(char));
        _exit(0);
    } else {    /* father process */
        close(my_pipe[1]);
        wait(&status);    /* wait until son process finishes */
        printf("Son Status: %d\n",status);
        read(my_pipe[0],BUF_SIZE * sizeof(char));
        printf("Got from pipe: %s\n",buf);
        _exit(0);
    }
}

我最初的想法是wait(&status)存在问题,如果子进程无法完成,可能会导致程序无法终止。

在儿子的代码中,我相信如果管道中没有足够的空间,write将阻塞该进程,从而阻塞整个应用程序。

如果我的主张正确,我该如何证明?而且我不知道如何修复儿子的代码。

gmaj1986 回答:管道中父进程的wait()有什么问题

您对管道尺寸的假设是正确的,我可以用BUF_SIZE中的0x10000重现该问题。

但是解决方案不是在客户端,而是在父母一方。您只需要read()之前的wait(),当然,您应该始终使用返回码来确定已收到多少。父级的此修复程序不再导致阻塞:

    len = read(my_pipe[0],buf,BUF_SIZE * sizeof(char));
    if( len >= 0 ) {
            printf("Got %d from pipe\n",len );
    } else {
            perror( "read()" );
    }
    close(my_pipe[1]);
    wait(&status);    /* wait until son process finishes */
    printf("Son Status: %d\n",status);

在子进程中,您可以使用fcntl(my_pipe[1],F_SETFL,O_NONBLOCK);使用非阻塞IO,因此write()将发送尽可能多的内容,然后返回。当然,在这种情况下,其余数据将丢失。

本文链接:https://www.f2er.com/3095431.html

大家都在问