进程间通信

进程间通信方式:管道,共享内存,信号量,信号,消息队列。

1. 管道pipe:是一种半双工通信,且只能用于有亲缘关系(即父子关系)的进程间通信。
    管道是由内核管理的一个缓冲区(buffer),一个进程从管道一端输入数据,另一个进程从管道另一端读出数据。
    当管道中没有信息,从管道中读取信息(read())的进程会进入阻塞状态,知道另一端的进程放入信息。当管道满时,尝试向管道中放入信息(write())的进程也会阻塞,知道另一端的进程从管道中取出了信息。
    当两个进程都结束时,管道消失。
    从管道中读取数据是一次性操作,数据一旦被读出,它就从管道中被抛弃,释放空间以便写更多的数据。

2. 命名管道FIFO,半双工通信,但是允许无亲缘关系的进程间通信。

3. 共享内存:

共享内存是最为高效的进程间通信方式

进程直接读写内存,不需要任何数据的拷贝

共享内存是分配一块能被其他进程访问的内存,实现是通过将内存去映射到共享它的进程的地址空间,使这些进程间的数据传送不再涉及内核,即,进程间通信不需要通过进入内核的系统调用来实现

共享内存允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取操作读出,从而实现了进程间的通信。

采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于像管道和消息队里等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。共享内存是分配一块能被其他进程访问的内存,实现是通过将内存去映射到共享它的进程的地址空间,使这些进程间的数据传送不再涉及内核,即,进程间通信不需要通过进入内核的系统调用来实现;

内存映射 memory map机制使进程之间通过映射同一个普通文件实现共享内存,通过mmap()系统调用实现。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调read/write等文件操作函数。

或者通过shmget开辟共享内存:

•为了在多个进程间交换信息,内核专门留出了一块内存区(或者进程在自己的内存空间开辟一块共享内存)

•由需要访问的进程将其映射到自己私有地址空间

•进程直接读写这一内存区而不需要进行数据的拷贝,提高了效率

多个进程共享一段内存,需要依靠某种同步机制,如互斥锁和信号量等

共享内存编程步骤:

  1). 创建共享内存

    •函数shmget()

    •从内存中获得一段共享内存区域

  2). 映射共享内存

    •把这段创建的共享内存映射到具体的进程空间中

    •函数shmat()

  3). 使用这段共享内存

    •可以使用不带缓冲的I/O读写命令对其进行操作

  4). 撤销映射操作: 函数shmdt()

5). 删除共享内存: 函数shctl()

4. 信号

进程之间通信或操作的一种机制。信号可以在任何时候发送给某一进程,而无需知道该进程的状态。如果该进程并未处于执行状态,则该信号就由内核保存起来,直到该进程恢复执行时才传递给它。如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到该信号的阻塞被取消时才传递给进程。

信号是软件层次上对中断机制的一种模拟,是一种异步通信方式。信号可以在用户空间进程和内核之间直接交互。

1)硬件来源,例如按下了cltr+C,通常产生中断信号sigint

2)软件来源,例如使用系统调用或者命令发出信号。最常用的发送信号的系统函数是kill,raise,setitimer,sigation,sigqueue函数。软件来源还包括一些非法运算等操作。

一旦有信号产生,用户进程对信号产生的相应有三种方式:

1)执行默认操作,linux对每种信号都规定了默认操作。

2)捕捉信号,定义信号处理函数,当信号发生时,执行相应的处理函数。

3)忽略信号,当不希望接收到的信号对进程的执行产生影响,而让进程继续执行时,可以忽略该信号,即不对信号进程作任何处理。

有两个信号是应用进程无法捕捉和忽略的,即SIGKILL和SEGSTOP,这是为了使系统管理员能在任何时候中断或结束某一特定的进程。

5.  消息队列

就是一个消息的链表,是一系列保存在内核中消息的列表,用户进程可以向消息队列添加消息,也可以向消息队列读取消息。

消息队列与管道通信相比,其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。

6. 信号量

分为命名和匿名信号量。命名信号量通常用于不共享内存的进程之间(内核实现);匿名信号量可以用于线程通信(存放于线程共享的内存,如全局变量),或者用于进程间通信(存放于进程共享的内存,如System V/ Posix 共享内存)。

消息队列、共享内存:与System V 类似。

互斥锁mutex + 匿名信号量:线程通信

互斥锁mutex + 条件变量condition :线程通信

PV操作由P操作原语和V操作原语组成(原语是不可中断的过程)。对信号量进行操作,具体定义如下:

P(S):
①将信号量S的值减1,即S = S - 1;
②如果s >= 0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S):
①将信号量S的值加1,即S = S + 1;
②如果S > 0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。
信 号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时, 表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。

让我们来看一个具体的实例: 假设现在的执行场景是有三个线程A,B,C进入一个信号量为1的临界资源,

1. 当线程A进入时,执行P操作, sem=0,线程A继续执行.

2. 当线程B进入时,线程A假设仍在占用临界资源, B执行P操作,sem = -1,B进入等待队列。

3. 当线程C进入时,线程A假设仍在占用临界资源, C执行P操作,sem = -2,C进入等待队列

时间: 2024-10-08 10:03:25

进程间通信的相关文章

Linux进程间通信总结

Linux进程间通信总结 1. 管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: (1)管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: (2)只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): (3)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. (4)数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出

Xenomai 进程间通信方式

Xenomai 进程间通信方式分成Xenomai域内的IPC以及Xenomai域和Linux域之间的IPC, 目前采用的rtipc(RTDM驱动)的方式,主要是给用户空间提供socket接口,实时应用 通过调用对应的接口可以避免切换到Linux域而导致实时性降低.rtipc对应了三个协议: XDDP (Xenomai域和Linux域之间的IPC) IDDP和BUFP (Xenomai域内的IPC) 另外,原有的RT_PIPE机制仍旧支持,但从Xenomai 3开始就不支持了. http://ww

31、互斥锁与进程间通信

我们之前做了多进程并发,那么你们有没有发现问题.如果说多个进程共享同一个数据,比如抢火车票大家同时在客户端查看同时购买会出现什么问题呢?今天我们将讲述进程锁还有进程间通信,进程之间彼此隔离,他们需要一个第三方联系起来. 一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行的修改,没错,速度是慢了,牺牲了速度而保证了数据安全. 1.上厕所 先举个通俗易懂

一起talk C栗子吧(第八十五回:C语言实例--使用信号进行进程间通信二)

各位看官们,大家好,上一回中咱们说的是使用信号进行进程间通信的样例,这一回咱们接着上一回的内容,继续说该样例.闲话休提.言归正转. 让我们一起talk C栗子吧. 我们在上一回中举了使用信号进行进程间通信的样例,在该样例中.我们通过终端发出信号.当进程收到该信号后让它运行系统对信号定义的默认动作.这一回.我们再来举一个使用信号进行进程间通信的样例,只是.我们发送和处理信号的方式和上一回的样例不一样.在接下来的样例中,我们在一个进程中使用kill产生信号.在另外一个进程中接收而且依照自己的方式处理

进程间通信 详解

进程间通信(IPC)介绍 进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息. IPC的方式通常有管道(包括无名管道和命名管道).消息队列.信号量.共享存储.Socket.Streams等.其中 Socket和Streams支持不同主机上的两个进程IPC. 以Linux中的C语言编程为例. 一.管道 管道,通常指无名管道,是 UNIX 系统IPC最古老的形式. 1.特点: 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端.

(转载)linux下的僵尸进程处理SIGCHLD信号Linux环境进程间通信(五): 共享内存(下)

Linux环境进程间通信(五): 共享内存(下) 在共享内存(上)中,主要围绕着系统调用mmap()进行讨论的,本部分将讨论系统V共享内存,并通过实验结果对比来阐述两者的异同.系统V共享内存指的是把所有共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面. 系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内

st_vio——进程间通信接口抽象结构体

工作忙,学习忙,但还是得随便写点. st_vio,顾名思义,应该是指virtual IO,即虚拟IO.根据代码里的注释,这个是一个高度抽象的进程间通信接口结构体,mysql中,如果不是用C++类来抽象,那么就是用含函数指针的结构体来抽象,这也是C语言最常用的习惯. struct st_vio { my_socket sd; /* my_socket - real or imaginary套接字 */ HANDLE hPipe/* 看风格应该只用于Windows系统 */; my_bool loc

PHP进程及进程间通信

一.引言 进程是一个具有独立功能的程序关于某个数据集合的一次运行活动.换句话说就是,在系统调度多个cpu的时候,一个程序的基本单元.进程对于大多数的语言都不是一个陌生的概念,作为"世界上最好的语言PHP"当然也例外. 二.环境 php中的进程是以扩展的形式来完成.通过这些扩展,我们能够很轻松的完成进程的一系列动作. pcntl扩展:主要的进程扩展,完成进程创建于等待操作. posix扩展:完成posix兼容机通用api,如获取进程id,杀死进程等. sysvmsg扩展:实现system

Android开发——进程间通信之AIDL(二)

0.  前言 不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPC(Inter-Process Communication)即进程间通信.首先线程和进程是很不同的概念,线程是CPU调用的最小单元,进程一般在PC和移动设备上指一个程序或者一个应用,一个进程可以包含多个线程. IPC方式有很多,在Android中常用的IPC方式包括Bundle.文件.Messenger.AIDL.ContentProvider和Socket等方式. Android开发--进程间通信之AIDL(一

Android 中基于 Binder的进程间通信

摘要:对  Binder 工作机制进行了分析. 首先简述 Android 中 Binder 机制与传统的 Linux 进程间的通信比较,接着对基于 Binder 进程间通信的过程分析 最后结合开发实例 (AIDL),了解 基于 Binder的进程间通信. 1.Android 采用 Binder 作为 IPC (Internet Process Connection) 机制的优势     Linux已经拥有的进程间通信IPC手段包括(Internet Process Connection): 管道