Linux中进程的通信方式一:管道

无名管道

  只能用于具有亲缘关系的进程间通信

        无名管道创建后,进程会获得操作管道的两个文件描述符,创建子进程时,子进程会拷贝得到父进程的操作无名管道的两个文件描述符,

函数接口:pipe 

pipe

int pipe(int pipefd[2]);
        功能:
            创建一个用来通信的管道
        参数:
            pipefd:存放管道两端(读写)的文件描述符数组
        成功返回0 
        失败返回-1 

   举例:两个进程任务操作同一管道实现通信。(父子进程)

#include "../head.h"
int main()
{
    pid_t pid;
    char tmpbuff[1024]={0};
    int pip[2]={0};
    int size=0;
    pipe(pip);
    pid=fork();
    if(pid==-1)
    {
        return -1;
    }
//父进程负责写
    if(pid==0)
    {
        strcpy(tmpbuff,"hello world");
        write(pip[1],tmpbuff,strlen(tmpbuff));
    }
//子进程负责读
    else if(pid>0)
    {

       size=read(pip[0],tmpbuff,sizeof(tmpbuff));//要是有一个写端,读端一直阻塞等待
        printf("tmpbuff=%s,读到的字节数为%d\n",tmpbuff,size);
    }
    return 0;
}

      注意 :

        1.如果管道中至少有一个写端:
            如果管道中有数据,直接读出
            如果管道中没有数据,会阻塞等待直到有数据写入后读出
        
        2.如果管道中没有写端:
            如果管道中有数据,直接读出 
            如果管道中没有数据,不会阻塞直接继续向下执行

        3.如果管道中至少有一个读端:
            如果管道没有写满,直接写入
            如果管道中写满(64k),则阻塞等待,等有数据读出才能继续写入

        4.如果管道中没有读端:
            向管道中写入数据会产生管道破裂信号

有名管道 

  通过管道在文件系统中的路径找到管道名,两个进程以读写的方式打开同一管道完成通信
有名管道必须读写两端同时加入后,才能继续向下执行

函数接口: mkfifo

   mkfifo
        int mkfifo(const char *pathname, mode_t mode);
        功能:
            创建一个管道 
        参数:
            pathname:管道文件的路径 
            mode:权限
        返回值:
            成功返回0 
            失败返回-1 

举例:write.c给管道中写数据

#include "../head.h"
extern int errno;
int main()
{
    int fd=0;
    int ret=0;
    char tmpbuff[1024]={0};
    ret=mkfifo("/tmp/myfifo",0664);
    if(ret==-1 && errno!=EEXIST)
    {
        perror("failed to myfifo");
        return -1;
    }
    fd=open("/tmp/myfifo",O_WRONLY);
    if(fd==-1)
    {
        perror("failed to open");
        return -1;
    }
    printf("打开管道成功!\n");
    write(fd,"hello world",11);
    close(fd);
    return 0;
}

 read.c从管道中读数据

#include "../head.h"

extern int errno;
int main()
{
    int fd=0;
    int ret=0;
    size_t size=0;
    char tmpbuff[1024]={0};
    ret=mkfifo("/tmp/myfifo",0664);
    if(ret==-1 && errno!=EEXIST)
    {
        perror("failed to myfifo");
        return -1;
    }
    fd=open("/tmp/myfifo",O_RDONLY);
    if(fd==-1)
    {
        perror("failed to open");
        return -1;
    }
    printf("打开管道成功!\n");
    size=read(fd,tmpbuff,sizeof(tmpbuff));
    printf("tmpbuff=%s,读到的字节为%ld\n",tmpbuff,size);
    close(fd);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值