原文地址:https://www.linuxidc.com/Linux/2018-04/151680.htm

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

1.进程间通信

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

2、进程间通信方式

一、进程间通信-管道 https://www.linuxidc.com/Linux/2018-04/151680.htm

二、进程间通信-命名管道 https://www.linuxidc.com/Linux/2018-04/151681.htm

三、进程间通信-消息队列 https://www.linuxidc.com/Linux/2018-04/151682.htm

四、进程间通信-共享内存 https://www.linuxidc.com/Linux/2018-04/151683.htm

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

本文永久更新链接地址https://www.linuxidc.com/Linux/2018-04/151680.htm

Linux进程间通信-管道深入理解(转)的更多相关文章

  1. Linux进程间通信—管道

    Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...

  2. Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字

    Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...

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

    前言    进程是一个独立的资源管理单元,不同进程间的资源是独立的,不能在一个进程中访问另一个进程的用户空间和内存空间.但是,进程不是孤立的,不同进程之间需要信息的交互和状态的传递,因此需要进程间数据 ...

  4. Linux进程间通信---管道和有名管道

    一.管道 管道:管道是一种半双工的通信方式,数据只能单方向流动,而且只能在具有亲缘关系的进程间使用,因为管道 传递数据的单向性,管道又称为半双工管道.进程的亲缘关系通常是指父子进程关系. 管道的特点决 ...

  5. 详解linux进程间通信-管道 popen函数 dup2函数

    前言:进程之间交换信息的唯一方法是经由f o r k或e x e c传送打开文件,或通过文件系统.本章将说明进程之间相互通信的其他技术-I P C(InterProcess Communication ...

  6. Linux 进程间通信(管道、共享内存、消息队列、信号量)

           进程通信 : 不同进程之间传播或交换信息    为什么要进程通信呢? 协同运行,项目模块化 通信原理 : 给多个进程提供一个都能访问到的缓冲区. 根据使用场景,我们能划分为以下几种通信 ...

  7. linux进程间通信-管道

    一 管道的局限性 管道有两个局限性:(1)他是半双工(即数据只能在一个方向上流动).(2)它只能在具有公共祖先的进程之间使用.一个管道由一个进程创建,然后该 进程调用fork,此后父子进程之间就可该管 ...

  8. Linux 进程间通信(二) 管道

    Linux 进程间通信-管道 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源.但是,进程不是孤立的,不同的进程之间需要信息的交换以及 ...

  9. Linux进程间通信(IPC)机制总览

    Linux进程间通信 Ø  管道与消息队列 ü  匿名管道,命名管道 ü  消息队列 Ø  信号 ü  信号基础 ü  信号应用 Ø  锁与信号灯 ü  记录锁 ü  有名信号灯 ü  无名信号灯(基 ...

随机推荐

  1. HDU_1175_A*

    http://acm.split.hdu.edu.cn/showproblem.php?pid=1043 刚开始一脸蒙逼,看了题解之后,参考了A*算法. 参考:http://www.cnblogs.c ...

  2. lua学习之基础概念篇

    基础概念 程序块 (chunk) 定义 lua 中的每一个源代码文件或在交互模式(Cmd)中输入的一行代码都称之为程序块 一个程序块就是一连串语句或者命令 lua 中连续的语句不需要分隔符,但为了可读 ...

  3. LeetCode 23 Hard,K个链表归并

    本文始发于个人公众号:TechFlow,原创不易,求个关注 链接 Merge k Sorted Lists 难度 Hard 描述 Merge k sorted linked lists and ret ...

  4. Linux命令行与Shell脚本编程大全

    快来参加<Linux命令行与Shell脚本编程大全>学习吧,提升技能,展示自我. 点击链接即可进入学习:https://s.imooc.com/WTmCO6H 课程亮点适合零基础读者,从零 ...

  5. centos下升级php到5.6

    今天正好用空把php环境升级到5.6版本,首先我之前的环境是源码包编译的lnmp环境 首先到php官方网站上下载一个php5.6的tar包,放到机器上面后,开始安装,安装前先将nginx,mysql, ...

  6. 深入了解MySQL,一篇简短的总结

    MySQL的基本语法 这里作为MySQL部分模块的深入了解,大部分都是理论方面的笔记,不会写具体用法. 具体用法会记录在下面这个随笔分类下,不过暂时还没更新完,等过段时间会更新下事务.存储过程.索引等 ...

  7. 13-Servlet&Request

    今日内容: 1. Servlet 2. Request Servlet 1. 概念 2. 步骤 3. 执行原理 4. 生命周期 5. Servlet3.0注解配置 6. Servlet的体系结构 se ...

  8. javascript Math对象 常用数字操作方法

    var t='1.2'; parseInt(t) parseFloat(t)//1.2 Number(1.2)//1.2强制转换为数字 2.向上取整,有小数就整数部分加1 js: Math.ceil( ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统--网页版本代码生成器

    1.单列表模式 2.树形列表模式 3.左右列表模式 4.左右树形和列表结合模式 一 简介 网页版代码生成器需要运行项目,非常有趣,可以用来研究,和自定义一些自己的代码习惯 按界面生成:可生成单个页面和 ...

  10. expect 运行脚本文件 执行postgres数据库操作

    #!/bin/bash /usr/bin/expect << EOF spawn /usr/local/pgsql/bin/.sh expect "*postgres:" ...