*常用到的不同主机间进程通讯:Socket。比如:host和引擎间socket指令通讯、分派和复判之间指令通讯;
*共享内存:在Windows系统中,共享内存的实现通常有以下几种方式:
1.内存映射文件(最常用):(windows下用:CreateFileMapping\MapViewOfFile\UnmapViewOfFile)
这是最常见的实现共享内存的方式。通过将磁盘上的文件映射到内存地址空间,文件的内容可以被映射到多个进程的地址空间,从而实现共享。
比如:从共享内存中获取图像/将图像导入共享内存;
2.命名管道:
虽然主要用于进程间的消息传递,命名管道也可以配置为在内存中传输数据,从而模拟共享内存的效果。
3.剪贴板:
剪贴板提供了一种将数据存储在共享内存中的方法,这样不同的程序可以访问和修改这些数据。
4.全局原子表:
全局原子表允许程序创建小段的、全局可访问的数据(原子),这些数据可由其他程序读取和修改。
一、支持不同主机间的进程通信方式主要有套接字。(既可以不同主机间的进程,也可以同一个主机内进程)
套接字(Socket)是一种网络通信机制,允许不同主机上的进程进行通信。它通过使用IP地址和端口号来建立连接,实现不同主机间的数据传输和交换信息12。
此外,还有一些其他进程间通信方式,但它们主要用于同一主机上的进程通信:
- 管道:主要用于父子进程或具有亲缘关系的进程之间进行通信2。
- 消息队列:通过在内核中创建消息队列实现多个进程之间的异步通信2。
- 共享内存:将一块共享内存映射到多个进程的虚拟地址空间中,实现进程间的数据共享2。
- 信号量:用于进程之间的同步与互斥操作2。
- 信号:用于进程之间的异步通信,实现简单的通知和事件传递2。
二、进程间通信主要包括:管道, 系统IPC(包括消息队列,信号量,共享存储), SOCKET.
2.1: 管道与文件描述符,文件指针的关系?
答: 其实管道的使用方法与文件类似,都能使用read,write,open等普通IO函数. 管道描述符来类似于文件描述符. 事实上, 管道使用的描述符, 文件指针和文件描述符最终都会转化成系统中SOCKET描述符. 都受到系统内核中SOCKET描述符的限制. 本质上LINUX内核源码中管道是通过空文件来实现.
2.2: 管道的使用方法?
答: 主要有下面几种方法: 1)pipe, 创建一个管道,返回2个管道描述符.通常用于父子进程之间通讯. 2)popen, pclose: 这种方式只返回一个管道描述符,常用于通信另一方是stdin or stdout; 3)mkpipe: 命名管道, 在许多进程之间进行交互.
2.3: 管道与系统IPC之间的优劣比较?
答: 管道: 优点是所有的UNIX实现都支持, 并且在最后一个访问管道的进程终止后,管道就被完全删除;缺陷是管道只允许单向传输或者用于父子进程之间.
系统IPC: 优点是功能强大,能在毫不相关进程之间进行通讯; 缺陷是关键字KEY_T使用了内核标识,占用了内核资源,而且只能被显式删除,而且不能使用SOCKET的一些机制,例如select,epoll等.
2.4: WINDOS进程间通信与LINUX进程间通信的关系?
答: 事实上,WINDOS的进程通信大部分移植于UNIX, WINDOS的剪贴板,文件映射等都可从UNIX进程通信的共享存储中找到影子.
2.5: 进程间通信与线程间通信之间的关系?
答: 因为WINDOWS运行的实体是线程, 狭义上的进程间通信其实是指分属于不同进程的线程之间的通讯.而单个进程之间的线程同步问题可归并为一种特殊的进程通信.它要用到内核支持的系统调用来保持线程之间同步. 通常用到的一些线程同步方法包括:Event, Mutex, 信号量Semaphore, 临界区资源等.
三、
管道(pipe):
管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
有名管道(namedpipe) :
有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量(semophore) :
信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列(messagequeue):
消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号(sinal):
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存(shared memory):
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。
共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
套接字(socket):
套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同设备及其间的进程通信。
四、进程间通信方式及其优缺点
1、匿名管道 Pipe
原理:基于操作系统内核提供的缓冲区,它通过将一个进程的输出连接到另一个进程的输入来实现进程间通信。当一个进程向管道中写入数据时,数据会被存储在管道的缓冲区中,等待另一个进程从管道中读取数据,没读取之前写入进程不会阻塞,除非缓冲区已满。当另一个进程从管道中读取数据时,数据会从缓冲区中被读取出来,并被传递给该进程,并被传递给该进程,没有数据来时,阻塞等待(因此是同步通信)。(总结:半双工通信,数据单向流动;只能在具有亲缘关系的进程间使用)
优点:简单方便;
缺点:局限于单向通信;只能创建在它的进程以及其有亲缘关系的进程之间;缓冲区有限。
2、命名管道 FIFO
原理:命名管道的原理与匿名管道类似,也是基于操作系统内核提供的缓冲区来实现进程间通信的。当一个进程向命名管道中写入数据时,数据会被存储在命名管道的缓冲区中,等待另一个进程从命名管道中读取数据,没读取之前写入进程不会阻塞,除非缓冲区已满。当另一个进程从命名管道中读取数据时,数据会从缓冲区中被读取出来,并被传递给该进程,没有数据来时,阻塞等待(因此是同步通信)。
优点:可以实现任意关系的进程间的通信;
缺点:长期存于系统中,使用不当容易出错;缓冲区有限。
3、消息队列 message queue
原理:
3.1 消息队列是一种先进先出的队列型数据结构,实际上是系统内核中的一个内部链表。消息被顺序插入队列中,其中发送进程将消息添加到队列末尾,接受进程从队列头读取消息。
3.2 多个进程可同时向一个消息队列发送消息,也可以同时从一个消息队列中接收消息。发送进程把消息发送到队列尾部,接受进程从消息队列头部读取消息,消息一旦被读出就从队列中删除。
优点:可以实现任意进程间的通信,并通过系统调用函数来实现消息发送和接收之间的同步,无需考虑同步问题,方便;
缺点:信息的复制需要额外消耗CPU的时间,不适宜于信息量大或操作频繁的场合。
4、共享内存 shared memory
原理:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC(进程间通信)方式,它是针对其它进程间通信方式运行效率低而专门设计的。
优点:无须复制,快捷,信息量大。
缺点:共享内存只是提供了数据共享的机制,但是并没有提供同步和互斥的机制。
5、信号量 semophore
原理:信号量通常是一个整数变量,用于记录某个共享资源的可用数量,它可以被多个线程或进程同时访问和修改。(信号量本质是一个计数器)
优点:可以同步进程;
缺点:不支持消息传递,只能做同步互斥,功能局限。
6、信号 signal
原理:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。主要作为进程间以及同一进程不同线程之间的同步手段。对于 Linux来说,实际信号是软中断,许多重要的程序都需要处理信号。例如,终端用户输入了 ctrl+c 来中断程序,会通过信号机制停止一个程序。
进程发送信号:通过kill、raise、alarm等函数发送信号给目标进程。
进程接收信号:通过signal、sigaction等函数注册信号处理函数。
当信号来时调用处理函数,在函数中根据信号作出相应处理。
优点:不同信号可以传递不同的信息。通过为每个信号定义相应的处理函数可以实现相对灵活的通信。
缺点:传递信息少。
7、套接字 socket
原理:套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
优点:1)传输数据为字节级,传输数据可自定义,数据量小效率高;2)传输数据时间短,性能高;3) 适合于客户端和服务器端之间信息实时交互;4) 可以加密,数据安全性强
缺点:1) 需对传输的数据进行解析,转化成应用级的数据。
原文链接:https://blog.csdn.net/qq_41709234/article/details/132007328
五、参考原文链接:
进程间通信方式:分类、区别、优缺点、使用场景
分类 | 特点 | 具体通信方式 |
---|---|---|
低级通信 | 控制信息的传送 | 信号 |
高级通信 | 与大批数据传送 | 管道、消息队列、共享内存、套接字 |
通信方式 | 介绍 | 区别 | 优缺点 | 使用场景 |
---|---|---|---|---|
管道pipe | 两种限制, 一是半双工,只能单向传输; 二是只能在父子进程间使用. | 优:无名管道简单方便 缺:单项传输、只父子进程 | 只能在具有亲缘关系的进程间使用.一般指的是父子关系.管道一般用于两个不同进程之间的通信. | |
流管道 | 双向传输. 只能在父子进程间使用 | 只能在父子进程间使用 | ||
有名管道 | 单向传输; 可以在许多并不相关的进程之间进行通讯. | 优点:可以提供给任意关系的进程使用. 缺点:由于其长期存在于系统之中,使用不当容易出错.所以普通用户一般不建议使用 | 允许无亲缘关系进程间的通信 | |
信号(Signal) | 由用户、系统或者进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常。 | 优点:触发某些行为 缺点:传递信息少 | 用户传递的信息较少;用于通知接收进程某个事件已经发生;发送信号给进程本身 | |
信号量(semaphore) | 是一个特殊的变量,它的本质是计数器,信号量里面记录了临界资源的数目,有多少数目,信号量的值就为多少,进程对其访问都是原子操作(pv操作,p:占用资源,v:释放资源)。 它的作用就是,调协进程对共享资源的访问,让一个临界区同一时间只有一个进程在访问它。 主要作为进程间以及同一进程不同线程之间的同步手段 | 信号是通知进程产生了某个事件, 信号量是用来同步进程的 | 用于多线程之间的同步,常与共享内存配合使用 | |
消息队列 (Message) | 消息队列是消息的链接表,包括Posix消息队列systemV消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。 允许任意进程通过共享消息队列来实现进程间通信.并由系统调用函数来实现消息发送和接收之间的同步.从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题 | 消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点 | 优点:不再局限于父子进程,不再需要考虑同步问题.使用方便 缺点:消息队列中信息的复制需要额外消耗CPU的时间.不适宜于信息量大或操作频繁的场合。 | 消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点. UNIX允许不同进程将格式化的数据流以消息队列形式发送给任意进程. |
共享内存 | 使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。 往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。 | 共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息 | 优点:无须复制,快捷、信息量大 缺点:1、通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的.因此,这些进程之间的读写操作的同步问题操作系统无法实现。必须由各进程利用其他同步工具解决 2、由于内存实体存在于计算机系统中.所以只能由处于同一个计算机系统中的诸进程共享,不方便网络通信 | 与其他通信机制,如信号量,配合使用,来实现进程间的同步与通信 |
套接口(Socket)🌟 | 对于网站,通信模型是服务器与客户端之间的通信。两端都建立了一个 Socket 对象,然后通过 Socket 对象对数据进行传输。通常服务器处于一个无限循环,等待客户端的连接。 | 用于不同进程及其间进程的通信 ;不同计算机之间的通信 |
不同问法都是围绕其特点说。
六、参考原文链接:进程间通信的6种方式 - 一杯清酒邀明月 - 博客园
1、管道:
1)管道传输数据是单向的,如果想相互通信,需要建立两个管道。
2)管道这种通信方式效率低, 不适合进程间频繁地交换数据。
3)优点是简单,很容易得知管道里的数据已经被另一个进程读取了。
2、消息队列:
1)消息队列是保存在内核中的消息链表,AB进程互相发送消息,只要把数据放在消息队列即可,之后进程遍可以正常返回,另一个进程会从消息队列中读取数据。
2)缺点:消息队列通信过程中,存在用户态与内核态之间的数据拷贝开销。
3、共享内存:
1)操作系统对于内存管理,采用的是虚拟内存技术,也就是每个进程都有自己独立的虚拟内存空间,不同进程的虚拟内存映射到不同的物理内存中。所以,即使进程A和 进程B的虚拟地址是一样的,其实访问的是不同的物理内存地址,对于数据的增删查改互不影响。
2)共享内存的机制,就是拿出一块虚拟地址空间来,映射到相同的物理内存中。这样这个进程写入的东西,另外一个进程马上就能看到了,都不需要拷贝来拷贝去,传来传去, 大大提高了进程间通信的速度。
3)缺点:当多个进程向同一个共享内存中写入数据时可能会产生覆盖(如在工作中,当多人同时修改一份共享文档时别人可能会将你添加的内容修改删除或覆盖),如果只读则没有任何问题。
4、信号量:
1)为了防止多进程竞争共享资源,而造成的数据错乱,所以需要保护机制,使得共享的资源,在任意时刻只能被一个进程访问。正好,信号量就实现了这一保护机制。
2)信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步。
3)信号量表示资源的数量,控制信号量的方式有两种原子操作:
- 一个是P操作,这个操作会把信号量减去1,相减后如果信号量<0,则表明资源已被占用,进程需阻塞等待;相减后如果信号量>=0,则表明还有资源可使用,进程可正常继续执行。
- 另一个是V操作,这个操作会把信号量加上1,相加后如果信号量<=0,则表明当前有阻塞中的进程,于是会将该进程唤醒运行;相加后如果信号量>0,则表明当前没有阻塞中的进程。
举例说明:
A:如果要使得两个进程互斥访问共享内存,我们可以初始化信号量为1。
具体的过程如下:
- 进程A在访问共享内存前,先执行了P操作,由于信号量的初始值为1,故在进程A执行P操作后信号量变为0,表示共享资源可用,于是进程A就可以访问共享内存。
- 若此时,进程B也想访问共享内存,执行了P操作,结果信号量变为了-1,这就意味着临界资源已被占用ェ因此进程B被阻塞。
- 直到进程A访问完共享内存,才会执行V操作,使得信号量恢复为0,接着就会唤醒阻塞中的进程B,使得进程B可以访问共享内存,最后完成共享内存的访问后,执行 V操作,使信号量恢复到初始值1。
可以发现,信号初始化为1,就代表着是互斥信号量,它可以保证共享内存在任何时刻只有一个进程在访问,这就很好的保护了共享内存。
B:用信号量来实现多进程同步的方式,我们可以初始化信号量为0。
具体过程如下:
- 如果进程B比进程A先执行了,那么执行到P操作时,由于信号量初始值为0,故信号量会变为-1,表示进程 A 还没生产数据,于是进程B就阻塞等待。
- 当进程A生产完数据后,执行了V操作,就会使得信号量变为0,于是就会唤醒阻塞在P操作的进程B。
- 进程B被唤醒后,意味着进程A已经生产了数据,于是进程B就可以正常读取数据了。
可以发现,信号初始化为0,就代表着是同步信号量,它可以保证进程A应在进程B之前执行。
5、信号:
1)信号一般用于一些异常情况下的进程间通信,是一种异步通信,它的数据结构一般就是一个数字。
2)信号是进程间通信机制中唯一的异步通信机制。
3)进程需要为信号设置相应的监听处理,当收到特定信号时,执行相应的操作,类似很多编程语言里的通知机制。
6、套接字:
1)前面提到的管道、消息队列、共享内存、信号量和信号都是在同一台主机上进行进程间通信,那要想跨网络与不同主机上的进程之间通信,就需要Socket通信了。
2)Socket通信不仅可以跨网络与不同主机的进程间通信,还可以在同主机上进程间通信。
七、windows、linux进程通讯方式对比
windows进程间同步方式有:1. 互斥量 mutex 2. 信号量 semaphore 3.事件 event 4.临界区 Critical Section 5.互锁函数;
临界区和互锁函数没有相应的内核对象因而不能跨进程;
linux进程同步方式有:互斥量、读写锁、条件变量;
linux内核同步方法:原子操作、自旋锁、读-写自旋锁、信号量、读-写信号量、完成变量、BKL、禁止抢占(preemp_disable()、preemp_enable());
windows的进程间的通信方式有:1.文件映射;2. 共享内存(是文件映射的一种特殊情况);3.邮件槽(mailslot)(点对点消息队列); 4.匿名管道;5;命名管道; 6. 剪贴板;7.动态数据交换;8.对象链接与嵌入;9.远程过程调用;10.动态链接库;11.socket;12.WM_COPYDATA ;
linux进程间通信的方式有:1.管道 2.信号量 3.共享内存 4.消息队列 5.套接字 6.信号;
windows和linux共有的进程间通信方式:1. 消息(linux中叫做信号) 2. 共享内存 3. 邮槽 4. 管道 5.socket;