【IPC通信】匿名管道

管道是最初的IPC方式,经常会在shell命令中使用。

引用《UNIX网络编程》上例子:

我们在某个Unix shell中输入下面的命令:

who | sort | lp

这个shell包含三个命令,who命令的输出(通过管道)做为sort命令的输入,sort的输出做为lp命令的输入,最终显示lp命令的输出。

这里暂不关心每个命令的作用,只考虑管道是如何传递的。

shell会创建三个进程分别执行这三个命令,三个进程间通过管道进行数据传输。如下图所示:

【IPC通信】匿名管道_第1张图片

接下来通过程序进行模拟,为方便起见,我们只考虑两个命令通过管道通信。

比如执行shell命令:命令1 | 命令2

命令1、命令2会由shell的两个子进程分别执行,两命令对应的两个进程不妨叫做大儿子、小儿子。

大儿子会对其弟弟问好,小儿子接收其哥哥的信息并打印到标准输出。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/*主进程fork两个子进程,两子进程通过管道传递数据*/
int main()
{
    int fields[2];
    char buf[100];
    int pid1, pid2;

    // 创建一个管道
    if(pipe(fields) < 0 )
    {
        perror("创建管道失败!");
    }

    // 父进程创建第一个儿子
    if((pid1 = fork()) < 0)
    {
        perror("创建子进程失败");
    }

    if(0 == pid1) // 大儿子
    {
        printf("大儿子有话对兄弟说: Hi,how are you?\r\n");
        char words[] = "Hi,how are you?";
        write(fields[1], words, sizeof(words));
    }
    
    if(pid1 > 0 ) // 父进程
    {
        // 父进程创建第二个儿子
        if((pid2 = fork()) < 0)
        {
            perror("创建子进程失败");
        }

        if(0 == pid2) // 小儿子
        {
            printf("小儿子接收哥哥的信息:");
            read(fields[0], buf, sizeof(buf));
            printf("%s\r\n", buf);
        }

        if(pid2 > 0)
        {
            waitpid(pid1, NULL, 0);
            waitpid(pid2, NULL, 0);
        }
    }

    return 0;
}

编译并执行:

$ gcc pipe.c

$ ./a.out

大儿子有话对兄弟说: Hi,how are you?

小儿子接收哥哥的信息:Hi,how are you?

 

2011-11-11 任洪彩 [email protected]

转载请注明出处。

 

 

你可能感兴趣的:(c,shell,ipc,管道)