如何等待数据写入管道的另一端

Use*_*007 5 c ipc pipe

我正在用C开发一个应用程序.父子进程通过管道进行通信.在写入管道之前,父进程执行另一个语句.在示例代码中,我使用sleep(10)来延迟.在子进程中,它应该从管道中读取数据.但是在子进程的管道读取端没有读取数据.

int main()
{
    int pid;
    FILE *fp;
    fp = fopen("test.txt","w");
    char *buff;
    int fd[2];
    int count = 0 ;
    pipe(fd);
    pid = fork();
    if(pid == 0)
    {
        close(fd[1]);
        ioctl(fd[0], FIONREAD, &count);
        fprintf(fp,"Value of count: %d ",count);
        buff = malloc(count);
        fprintf(fp,"\n TIME before read: %s",__TIME__);
        read(fd[0], buff, count);
        fprintf(fp,"\nbuffer: %s\n TIME after read %s", buff, __TIME__);
    }
    else{
        close(fd[0]);
        sleep(10);    //delay caused by application specific code replaced with sleep
        write(fd[1],"THIS is it",10);
    }
    fclose(fp);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何使子进程等到数据写入另一端?

Who*_*aig 5

你的管道是在阻塞模式下打开的,你没有做任何改变,这可能是你想要的.

但是,由于您要做的第一件事是请求管道上等待的数据大小,然后盲目地跳入读取许多字节(由于父代尚未写入任何内容,因此在代码执行时很可能为零)你不要阻止,而只是因为你没有要求而离开.

有很多方法可以做到这一点,包括选择循环.如果您希望阻止读取直到数据可用,则在单个字节上执行此操作,然后填写剩余数据.

这绝不是如何正确执行此操作的示例,但它是一个简短的示例,说明如何等待单个字节,请求管道的读取大小以获取其余数据,读取它,以及继续这个,直到管道没有数据,父节点关闭它们的结束:

我希望你觉得这对你有帮助.

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

int main()
{
    int pid = 0;

    // create pipe pair
    int fd[2];
    pipe(fd);

    pid = fork();
    if (pid == 0)
    {
        // child side
        char *buff = NULL;
        char byte = 0;
        int count = 0;

        // close write side. don't need it.
        close(fd[1]);

        // read at least one byte from the pipe.
        while (read(fd[0], &byte, 1) == 1)
        {
            if (ioctl(fd[0], FIONREAD, &count) != -1)
            {
                fprintf(stdout,"Child: count = %d\n",count);

                // allocate space for the byte we just read + the rest
                //  of whatever is on the pipe.
                buff = malloc(count+1);
                buff[0] = byte;
                if (read(fd[0], buff+1, count) == count)
                    fprintf(stdout,"Child: received \"%s\"\n", buff);
                free(buff);
            }
            else
            {   // could not read in-size
                perror("Failed to read input size.");
            }
        }

        // close our side
        close(fd[0]);
        fprintf(stdout,"Child: Shutting down.\n");
    }
    else
    {   // close read size. don't need it.
        const char msg1[] = "Message From Parent";
        const char msg2[] = "Another Message From Parent";
        close(fd[0]);
        sleep(5); // simulate process wait
        fprintf(stdout, "Parent: sending \"%s\"\n", msg1);
        write(fd[1], msg1, sizeof(msg1));
        sleep(5); // simulate process wait
        fprintf(stdout, "Parent: sending \"%s\"\n", msg2);
        write(fd[1], msg2, sizeof(msg2));
        close(fd[1]);
        fprintf(stdout,"Parent: Shutting down.\n");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量

Parent: sending "Message From Parent"
Child: count = 19
Child: received "Message From Parent"
Parent: sending "Another Message From Parent"
Parent: Shutting down.
Child: count = 27
Child: received "Another Message From Parent"
Child: Shutting down.
Run Code Online (Sandbox Code Playgroud)