【APUE】进程间通信之管道

管道是UNIX系统IPC最古老形式,并且所有UNIX系统都提供此种通信机制。管道由下面两种局限性:

1)历史上,它们是半双工的(即数据只能在一个方向上流动)

2)它们只能在具有公共祖先的进程之间使用。通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道

管道由调用pipe函数创建:

#include <unistd.h>

int pipe(int filedes[2]);//若成功则返回0,出错返回-1

注意:filedes[0]为读而打开,filedes[1]为写而打开,filedes[1]的输出是fileds[0]的输入

单个进程中的管道几乎没有任何作用。通常,调用pipe的进程接着调用fork,这样就创建了从父进程到子进程(或反向)的IPC通道。

调用fork后做什么取决于我们想要有的数据流的方向。对于从父进程到子进程的管道,父进程关闭管道的读端(fd[0]),子进程则关闭写端(fd[1]).

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define MAXLINE 100
//经由管道父进程向子进程传送数据
int main()
{
        int n;
        int fd[2];
        pid_t pid;
        char line[MAXLINE];

        if(pipe(fd)<0)
                printf("pipe error");
        if((pid=fork())<0)
                printf("fork error");
        else if(pid>0)
        {
                close(fd[0]);
                write(fd[1],"hello world\n",12);
        }
        else
        {
                close(fd[1]);
                n=read(fd[0],line,MAXLINE);
                write(STDOUT_FILENO,line,n);
        }
        exit(0);
}

采用管道实现双向通信需要两个管道,控制两个不同的数据流向。现在模拟一个Client和Server双向通信的过程,Client与Server之间 可以相互发送和接收信息。此时需要两个管道进行模拟,管道1模拟Server写Client读数据流向,管道2模拟Client写Server读数据流 向。代码如下所示:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<errno.h>
#include<string.h>

int main()
{
    int fd1[2],fd2[2];
    pid_t childpid;
    char buf[100];

    memset(buf,0,100);

    if(pipe(fd1)==-1)
    {
        perror("pipe()error");
        exit(-1);
    }
    if(pipe(fd2)==-1)
    {
        perror("pipe() error");
        exit(-1);
    }
    childpid=fork();
    if(childpid==0)
    {
        printf("server input a message:");
        gets(buf);
        close(fd1[0]);
        close(fd2[1]);
        write(fd1[1],buf,strlen(buf));
        read(fd2[0],buf,100);
        printf("server received message from client:%s\n",buf);
        exit(0);
    }
    if(childpid==-1)
    {
        perror("fork()error");
        exit(-1);
    }
    close(fd1[1]);
    close(fd2[0]);
    read(fd1[0],buf,100);
    printf("client received a message from server:%s\n",buf);
    printf("client input a message:");
    gets(buf);
    write(fd2[1],buf,strlen(buf));
    waitpid(childpid,NULL,0);
    return 0;
}

转载于:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/3855093.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值