Linux系统运维之Linux进程间通信-管道深入理解
白羽 2018-07-11 来源 :网络 阅读 738 评论 0

摘要:本文将带你了解Linux系统运维之Linux进程间通信-管道深入理解,希望本文对大家学Linux有所帮助。


Linux进程通信系列文章将详细介绍各种通信方式的机制和区别

1.进程间通信

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

 

2、进程间通信方式

一、进程间通信-管道

二、进程间通信-命名管道 三、进程间通信-消息队列

四、进程间通信-共享内存

3、进程间通信-管道(pipe)

 3.1 管道是如何通信的  

(1)父进程创建管道,得到两个⽂件描述符指向管道的两端

(2)父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道。

(3)父进程关闭fd[0],子进程关闭fd[1],即⽗进程关闭管道读端,⼦进程关闭管道写端(因为管道只支持单向通信)。⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。

 

3.2 利用管道实现通信

#include "stdio.h"
#include "unistd.h"
#include "string.h"

int main(int argc, char* argv[])
{
    int fd[2];
    int ret = pipe(fd);
    if (ret == -1)
    {
        perror("pipe error\n");
        return 1;
    }

    pid_t pid = fork();
    if (pid == 0)  // child
    {
        close(fd[0]);
        int i = 0;
        char* msg = "i am child\n";
        while (i < 5)
        {
            write(fd[1],msg,strlen(msg));
            sleep(2);
            i++;
        }

    }
    else if(pid > 0)
    {
        close(fd[1]);
        char buf[256] = {0};
        int j = 0;
        while (j < 5)
        {
            int n = read(fd[0],buf,256);
            if (n>0)  
            {  
                buf[n] = '\0';  
            }  
            printf("%s",buf);
            j++;  
        }
    }
    else
    {
        perror("fork error\n");
        return 1;
    }
    return 0;
}

运行结果:

 

 3.3 管道读取数据的四种的情况

(1)读端不读,写端一直写

 

(2)写端不写,读端一直读

 

(3)读端一直读,写端关闭

 

(4)写端一直写,读端关闭

 

#include "stdio.h"
#include "unistd.h"
#include "string.h"
#include "sys/wait.h"
#include "sys/types.h"

int main(int argc, char* argv[])
{
    int fd[2];
    int status = 0;
    int ret = pipe(fd);
    if (ret == -1)
    {
        perror("pipe error\n");
        return 1;
    }

    pid_t pid = fork();
    if (pid == 0)  // child
    {
        close(fd[0]);
        int i = 0;
        char* msg = "i am child\n";
        while (i < 10)
        {
            write(fd[1],msg,strlen(msg));
            sleep(1);
            i++;
        }

    }
    else if(pid > 0)
    {
        close(fd[1]);
        char buf[256] = {0};
        int j = 0;
        while (j < 5)
        {
            int n = read(fd[0],buf,256);
            if (n>0)  
            {  
                buf[n] = '\0';  
            }  
            printf("%s",buf);
            j++;  
        }
        close(fd[0]);
        ret = waitpid(pid,&status,0);
        printf("exit single(%d),exit(%d)\n", status & 0xff, (status >> 8) & 0xff);  
    }
    else
    {
        perror("fork error\n");
        return 1;
    }
    return 0;
}

运行结果:

 

使用kill -l 查看13号信号,可以知道13号信号代表SIGPIPE。

4、管道的特点

(1)管道只允许具有血缘关系的进程间通信,如父子进程间的通信。

(2)管道只允许单向通信。

(3)管道内部保证同步机制,从而保证访问数据的一致性。

5、管道的容量

测试管道容量大小只需要将写端一直写,读端不读且不关闭fd[0],即可。

#include "stdio.h"
#include "unistd.h"
#include "string.h"
#include "sys/wait.h"
#include "sys/types.h"

int main(int argc, char* argv[])
{
    int fd[2];
    int status = 0;
    int ret = pipe(fd);
    if (ret == -1)
    {
        perror("pipe error\n");
        return 1;
    }

    pid_t pid = fork();
    if (pid == 0)  // child
    {
        close(fd[0]);
        int i = 1;
        while (i)
        {
            write(fd[1],"A",1);
            printf("pipe capacity: %d\n",i++);
        }
        close(fd[1]);

    }
    else if(pid > 0)
    {
        close(fd[1]);
        waitpid(pid,NULL,0);
        close(fd[0]);
    }
    else
    {
        perror("fork error\n");
        return 1;
    }
    return 0;
}

运行结果:

 

由此可见,管道大小为64k

 


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标系统运维之Linux!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程