一、管道

管道是进程间通信中最古老的方式,所有UNIX都提供此种通信机制。管道有以下两种局限性:

  1. 历史上,他们是半双工的(即数据只能在一个方向上流动)。
  2. 管道只能在具有公共祖先的两个进程间使用。通常,一个管道由一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了。

FIFO没有第二种局限性。

尽管有这两种局限性,半双工管道仍然是最常用的IPC形式。

管道由pipe()函数创建:

#include <unistd.h>
int pipe(int fd[2]); 返回值:若成功,返回0,若出错,返回-1
参数fd返回两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。fd[1]的输出是fd[0]的输入。

通常,进程会先调用pipe,接着调用fork,从而创建从父进程到子进程的IPC通道,反之亦然。fork之后做什么取决于我们想要的数据流的方向。

对于从父进程到子进程的管道:父进程关闭管道的读端(fd[0]),子进程关闭写端(fd[1])。

对于从子进程到父进程的管道:父进程关闭管道的写端(fd[1]),子进程关闭读端(fd[0])。

 

二、FIFO

FIFO有时被称为命名管道,通过FIFO,不相关的进程也能交换数据。

FIFO由mkfifo()函数创建:

#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode); 返回值:若成功,返回0,若出错,返回-1

FIFO有如下两种用途:

  1. shell命令使用FIFO函数将数据从一条管道传送到另一条时,无需创建中间临时文件。
  2. 客户进程-服务器进程应用程序中,FIFO用作汇聚点,在客户进程和服务器进程二者之间传递数据。

 

三、消息队列

消息队列是消息的链接表,存储在内核中,由消息队列标识符标识。

客户进程和服务器进程之间的双向数据流。

msgget用于创建一个新队列或打开一个现有队列,msgsnd将新消息添加到队列尾端,每个消息包含一个正的长整型类型的字段、一个非负的长度(nbytes)以及实际数据字节数(对应于长度),msgrcv用于从队列中取消息。

#include <sys/msg.h>
int msgget(key_t key, int flag); 返回值:若成功,返回消息队列ID,若出错,返回-1
int msgsnd(int msgid, const void *ptr, size_t nbytes, int flag); 返回值:若成功,返回0,若出错,返回-1
ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag); 返回值:若成功,返回消息数据部分的长度,若出错,返回-1

 

四、信号量

本质上,信号量是一个计数器,用于为多个进程提供对共享数据对象的访问。

维护信号量状态的是Linux内核操作系统而不是用户进程。

一般说来,为了获得共享资源,进程需要执行下列操作:

  1. 测试控制该资源的信号量。
  2. 若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。
  3. 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
  4. 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。

 

五、共享存储

共享存储允许两个或多个进程共享一个给定的存储区。因为数据不需要在客户进程和服务器进程之间复制,所以这是最快的一种IPC。

通常,信号量被用来实现对共享存储数据存取的同步。(也可以用记录锁或互斥量)

shmget获得一个共享存储标识符,shmctl对共享存储段执行多种操作,shmat将共享存储段连接到它的地址空间。

#include<sys/shm.h>
int shmget(key_t key, size_t size, int flag); 返回值:若成功,返回共享存储ID;若出错,返回-1
int shmctl(int shmid, int cmd, struct shmid_ds *buf); 返回值:若成功,返回0;若出错,返回-1
void *shmat(int shmid, const void *addr, int flag); 返回值:若成功,返回指向共享存储段的指针;若出错,返回-1

 

六、网络IPC:套接字

不同计算机(通过网络相连)上的进程相互通信的机制:网络进程间通信(network IPC)。

套接字是通信端点的抽象。正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字。

socket创建一个套接字,shutdown禁止一个套接字的I/O。

#include <sys/socket.h>
int socket(int domain, int type, int protocol); 返回值:若成功,返回文件(套接字)描述符,若出错,返回-1
int shutdown(int sockfd, int how); 返回值:若成功,返回0,若出错,返回-1

进程间通信 IPC(Inter-Process Communication)的更多相关文章

  1. 【操作系统之三】Linux下进程间通信-IPC(Inter-Process Communication)

    管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:信号(Sign ...

  2. c# 进程间通信 IPC

    最近在调试一个算法,想通过改变算法的参数看看结果有什么变化. 碰到一个麻烦的事情是,从磁盘加载.构建数据需要15分钟.这就比较讨厌了,也就是说我每次调一个参数前都要等15分钟启动时间? 于是我就想,能 ...

  3. 进程间通信IPC -- 管道, 队列

    进程间通信--IPC(Inter-Process Communication) 管道 from multiprocessing import Pipecon1,con2 = Pipe()管道是不安全的 ...

  4. 【windows 操作系统】进程间通信(IPC)简述|无名管道和命名管道 消息队列、信号量、共享存储、Socket、Streams等

    一.进程间通信简述 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进 ...

  5. 进程间通信IPC (InterProcess Communication)

    一.进程间通信的概念 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区, ...

  6. Android进程间通信IPC

    一.IPC的说明 IPC是Inter-Process Communication的缩写,含义为进程间通信或跨进程通信,是指两个进程之间进行数据交换的过程. IPC不是Android独有的,任何一个操作 ...

  7. 进程间通信IPC之--无名管道(pipe)和有名管道(fifo)(转)

     进程间通信IPC之--无名管道(pipe)和有名管道(fifo) 2012-01-17 22:41:20 分类: C/C++ 每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中 ...

  8. 进程间通信IPC之--共享内存

    每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲 ...

  9. 3. 进程间通信IPC

    一.概念 IPC: 1)在linux环境中的每个进程各自有不同的用户地址空间.任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间是不能相互访问. 2)如果进程间要交换数据必须通过内核,在 ...

随机推荐

  1. node API

    看了这么久nodejs,它包含哪些基础的API,自己心中都没有数,该完整地看看基础的API了. 见过的: assert:编写程序的单元测试用例 buffer:直接处理2进制数据 child_proce ...

  2. map 小模板~~~ 写的不好 继续添加

    #include<map>#include<string.h>#include<iostream>using namespace std; int main(){  ...

  3. YOLO end-to-end

    1.YOLO: You Only Look Once:Unified, Real-Time Object Detection YOLO是一个可以一次性预测多个Box位置和类别的卷积神经网络,能够实现端 ...

  4. asp.net web api 跨域问题

    缘起 以前在asp.net mvc时代,很少出现跨域问题 自从使用了asp.net web api + angular (1/2)之后,开始有跨域问题了. 简单普及下跨域: 我的理解是只要是前台页面与 ...

  5. .Net Core Razor 预编译,动态编译,混合编译

    预编译 预编译是ASP .Net Core的默认方式.在发布时,默认会将系统中的所有Razor视图进行预编译.编译好的视图DLL统一命名为 xxx.PrecompiledViews.dll 或者 xx ...

  6. WPF放大镜效果

    在做WPF项目中,不止两个项目需要有放大镜功能. 第一个项目是一个手术室的远程示教系统,主要是为了方便专家演示病症时,可以放大图片上的某些部位. 第二个项目是一个工厂的MES项目,其中有个功能是质量预 ...

  7. javascript实现OOP编程

    1.首先通过一个函数来实现JS的单继承.使用原型方式来实现继承 (function () { $.extend({ oop: { extend: function (child, father) { ...

  8. UCore-Lab1

      日期:2019/3/31 内容:makefile分析: 一."Makefile"分析 1.1 ucore.img lab1已有的源文件 目录 文件 boot asm.h.boo ...

  9. Code Chef MINPOLY(计算几何+dp)

    题面 传送门 题解 我们枚举这个凸多边形\(y\)坐标最小的点\(p_i\),然后对于所有\(y\)坐标大于等于它的点极角排序 我们预处理出\(s_{j,k}\)表示三角形\(p_i,p_j,p_k\ ...

  10. Swift5 语言指南(二十) 类型转换

    类型转换是一种检查实例类型的方法,或者将该实例视为与其自己的类层次结构中的其他位置不同的超类或子类. Swift中的类型转换是使用is和as运算符实现的.这两个运算符提供了一种简单而富有表现力的方法来 ...