进程间通信-半双工管道(pipe)

 管道是针对本地计算机的两个进程之间的通信而设计的,管道建立后,实际获得两个文件描述符:一个用于读取而另外一个用于写入。任何从管道写入端写入的数据,可以从管道读取端读出。特点:

管道是半双工的,数据只能向一个方向流动,需要双方通信时,需要建立起两个管道。

只能用于父子进程或者兄弟进程之间

单独构成独立的文件系统:管道对于管道两端的进程而言,就是一个文件,它不属于某种文件系统,而是单独构成一种文件系统,并且只存在于内存

数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读取数据


fifo克服了管道,只有亲缘关系才能通信的瓶颈。这个下次再说。

例子:

#include 
#include 
#include 
#include 
#include 
#include 

/*define a function pid_printf*/
void pid_printf(char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    printf("[%d]%d:", getpid(),__LINE__);
    vprintf(format, ap);
}

/*chile write data to pipe*/
void child_process(int pfd[2])
{
    close(pfd[0]); //close unused read fd
    char buf[256];
    pid_printf("child process is ready.\n");
    pid_printf("enter message(ctrl+d to exit):");
    fflush(stdout);
    while(fgets(buf, sizeof(buf), stdin) != NULL)
    {
        pid_printf("Transmitting message:%s",buf);
        write(pfd[1], buf, strlen(buf));
    }
    pid_printf("child process exiting.\n");
    close(pfd[1]);
    _exit(EXIT_SUCCESS);
}

/*parent read data from pipe*/
void parent_process(int pfd[2])
{
    char buf[256] = {0};
    int count;
    int status;
    /*close unused write fd*/
    close(pfd[1]);
    pid_printf("parent process is ready.\n");
    while(1)
    {
        count = 0;
        while(count < sizeof(buf)-1)
        {
            status = read(pfd[0], buf+count, 1);
            if(status < 1)
            {
                pid_printf("read eof, parent exiting\n");
                close(pfd[0]);
                return;
            }
            if(buf[count] == '\n')
                break;
            count ++;
        }
        pid_printf("receive message:%s\n", buf);
    }
    pid_printf("no more data , parent exiting\n");
    close(pfd[0]);
}

int main(int argc, char *argv[])
{
    int pfd[2];
    pid_t pid;
    
    if(pipe(pfd) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    pid = fork();
    if(pid == 0)
    {
        child_process(pfd);
    }
    else if(pid!=-1)
    {
        parent_process(pfd);
    }
    return 0;
}
/*管道主要是使用pipe()函数*/















你可能感兴趣的:(C/C++语言)