进程间通信的四种方式

合集下载

【IT专家】进程间的五种通信方式介绍

【IT专家】进程间的五种通信方式介绍

进程间的五种通信方式介绍
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。

 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。

其中Socket和Streams支持不同主机上的两个进程IPC。

 以Linux中的C语言编程为例。

 一、管道管道,通常指无名管道,是UNIX 系统IPC最古老的形式。

 1、特点:它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。

但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

 一、管道管道,通常指无名管道,是UNIX 系统IPC最古老的形式。

 1、特点:它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。

但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

2、原型:1 #include unistd.h 2 int pipe(int fd[2]); // 返回值:若成功返回0,失败返回-1 当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。

如下图:。

安卓进程间通信的四种方式(含案例)

安卓进程间通信的四种方式(含案例)

安卓进程间通信的四种方式(含案例)Android通过进程间通信(IPC)技术来共享数据和资源,可以有效的提高应用程序的性能和可靠性。

Android共有四种进程间通信(IPC)方式:AIDL、ContentProvider、Messenger和Socket。

AIDL(Android Interface Definition Language)
AIDL(Android接口定义语言)是Android所提供的接口定义语言,可用于定义远程过程调用,也称为跨应用程序的远程过程调用(RPC)。

AIDL介绍远程调用的一种标准格式,可以实现不同应用之间的调用,非常适合用于安卓系统中的多进程通信。

案例:
AIDL应用示例:假设一个应用程序运行在安卓设备上,该应用程序既能监控设备的状态(如CPU使用率),也能向其他应用程序提供数据(如功耗数据)。

这时,如果要实现应用程序之间的交流,就需要使用AIDL,而且可以将AIDL程序集成到已有的应用程序中。

ContentProvider
ContentProvider是Android提供的IPC(进程间通信)机制,它可以被称为数据共享的另一种形式。

ContentProvider允许一个应用程序可以将它的数据共享给其他的应用程序,而不需要访问外部的数据库,这是一个非常安全有效的过程。

案例:。

进程通信的几种方式

进程通信的几种方式
匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,也不能用于两个不相关的进程之间。
2.4 命名管道
命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。
2.13 WM_COPYDATA消息
WM_COPYDATA是一种非常强大却鲜为人知的消息。当一个应用向另一个应用传送数据时,发送方只需使用调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了数据共享。
命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。
2.5 邮件槽
邮件槽(Mailslots)提供进程间单向通信能力,任何进程都能建立邮件槽成为邮件槽服务器。其它进程,称为邮件槽客户,可以通过邮件槽的名字给邮件槽服务器进程发送消息。进来的消息一直放在邮件槽中,直到服务器进程读取它为止。一个进程既可以是邮件槽服务器也可以是邮件槽客户,因此可建立多个邮件槽实现进程间的双向通信。
Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。

进程间通信的方式有哪些?

进程间通信的方式有哪些?

进程间通信的⽅式有哪些?
进程间通信的⽅式有哪些?
1、进程间通讯⽅式有:管道,信号,信号量,消息队列,共享内存,套接字共六种
2、管道:管道分为有名管道和⽆名管道,其中⽆名管道是⼀种半双⼯的通信⽅式,数据只能单向流动,⽽且只能在具有亲缘关系的进程间使⽤,⼀般⽤于两个不同进程之间的通信。

有名管道也是⼀种半双⼯的通信⽅式,但它允许⽆亲缘关系进程间的通信。

3、信号:信号是⼀种⽐较复杂的通信⽅式,信号产⽣的条件:按键、硬件异常、进程调⽤kill函数将信号发送给另⼀个进程、⽤户调⽤kill命令将信号发送给其他进程,传递的消息⽐较少⽤于通知接收进程某个时间已经发⽣
4、信号量:信号量是⼀个计数器,可以⽤来控制多个线程对共享资源的访问,它不是⽤于交换⼤批数据,⽽⽤于多线程之间的同步。

他常作为⼀种锁机制。

因此,主要作为进程间以及同⼀个进程内不同线程之间的同步⼿段
5、消息队列:消息队列是消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信号传递信息少,管道只能承载⽆格式字节流以及缓冲区⼤⼩受限等特点。

6、共享内存:共享内存就是映射⼀段能被其他进程所访问的内存,这段共享内存由⼀个进程创建,但多个进程都可以访问。

他往往与其他通信机制,如信号量配合使⽤,来实现进程间的同步和通信。

7、套接字:套接字可⽤于不同及其间的进程通信。

流式套接字: 提供可靠的,⾯向连接的通讯流
数据包套接字:定义⼀种⽆连接的服务,通过相互独⽴的报⽂进⾏传输,是⽆序的。

进程间通信方法

进程间通信方法

进程间通信方法
一、简介
进程间通信(Inter-Process Communication,IPC)是指两个或以上的进程之间的交互式通信联系,它可以用来实现进程间的数据交换、任务分配和调度等多种功能。

进程间通信属于分布式环境中的一部分,其中,计算机网络可以被看作是一种进程间通信的手段。

二、进程间通信方法
1. 管道(Pipe)
管道是进程间通信的最常用的方式,它是UNIX系统的一种文件类型,可以作为进程间双向通信的手段,每个管道类型的文件有两个端口,可以用来交换数据,管道的实现方式很简单,但是没有消息的概念,而且有一定的消息大小的限制,只能在同一操作系统中使用,不能跨不同的操作系统。

2. 消息传递(Message Passing)
消息传递是将信息传递给分布式进程,这种进程间通信的传输方式可以跨越多个计算机系统,而不仅仅是应用程序之间的通信。

消息传递在分布式系统中是必不可少的,它可以实现远程调用、异步调用、消息接收和消息发送等功能。

3. 共享内存(Shared Memory)
共享内存是一种在两个或多个进程之间共享的一段具有特定格
式的内存,它通常用来实现进程之间的数据交换,可以提高进程间的通信效率,但是它和消息传递一样,也需要进程间的协作,才能保证
共享内存的状态更新不冲突。

4. 信号量(Semaphore)
信号量是一种同步技术,用于控制多个进程的访问。

它常用于一个进程要建立一定的锁,来保护一段关键的代码,以避免其他进程并行访问可能造成的数据安全问题。

5. 信号(Signal)
信号是一种进程间通信的特殊方式,它可以跨越多个进程,用于控制多个进程之间的通信,常用于一个进程通知其他进程采取某种措施。

进程之间的四种通讯方式

进程之间的四种通讯方式
用于进程间通讯(IPC)的四种不同技术:
1. 消息传递(管道,FIFO,posix和system v消息队列)
2. 同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯)
3. 共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区)
4. 在众多的消息传递技术—管道,FIFO,Posix消息队列和System V消息队列—中,可从一个信号处理程序中调用的函数只有read和write(适用于管道和FIFO).
比较不同形式的消息传递时,我 们感兴趣的有两种测量尺度:
1. 带宽(bandwidth):数据通过IPC通道转移的速度.为测量该值,我们从一个进程向另一个进程发送大量数据(几百万字节).我们还给不同大小的 I/O操作(例如管道和FIFO的write和read操作)测量该值,期待发现带宽随每个I/O操作的数据量的增长而增长的规律.
2. 延迟(latency):一个小的IPC消息从一个进程到令一个进程再返回来所花的时间.我们测量的是只有一个1个字节的消息从一个进程到令一个进程再回 来的时间(往返时间)
Hale Waihona Puke 在现实世界中,带宽告诉我们大块数据通过一个IPC通道发送出去需花多长时间,然而IPC也用于传递小的控制信 息,系统处理这些小消息所需的时间就由延迟提供.这两个数都很重要.
4. 过程调用(Solaris门,Sun RPC)
消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区通常需要由应用程序提供的某种同步形式才能 正常工作.解决某个特定问题应使用哪种IPC不存在简单的判定,应该逐渐熟悉各种IPC形式提供的机制,然后根据特定应用的要求比较它们的特性.

进程间通信的几种方式

进程间通信的几种方式

进程间通信的⼏种⽅式典型回答1. 套接字套接字为通信的端点。

通过⽹络通信的每对进程需要使⽤⼀对套接字,即每个进程各有⼀个。

每个套接字由⼀个 IP 地址和⼀个端⼝号组成。

通常,套接字采⽤ CS 架构,服务器通过监听指定的端⼝,来等待特定服务。

服务器在收到请求后,接受来⾃客户端套接字的连接,从⽽完成连接。

2. 管道管道提供了⼀个相对简单的进程间的相互通信,普通管道允许⽗进程和⼦进程之间的通信,⽽命名管道允许不相关进程之间的通信。

知识延伸进程间通信有两种基本模型:共享内存和消息传递。

共享内存模型会建⽴起⼀块供协作进程共享的内存区域,进程通过向此共享区域读出或写⼊数据来交换信息。

消息传递模型通过在协作进程间交换信息来实现通信。

下图给出了两个模型的对⽐:很多系统同时实现了这两种模型。

消息传递对于交换较少数量的数据很有⽤,因为⽆需避免冲突。

对于分布式系统,消息传递也⽐共享内存更易实现。

共享内存可以快于消息传递,这是因为消息传递的实现经常采⽤系统调⽤,因此需要更多的时间以便内核介⼊。

与此相反,共享内存系统仅在建⽴共享内存区域时需要系统调⽤;⼀旦建⽴共享内存,所有访问都可作为常规内存访问,⽆需借助内核。

对具有多个处理核的系统上,消息传递的性能要优于共享内存。

共享内存会有⾼速缓存⼀致性问题,这是由共享数据在多个⾼速缓存之间迁移⽽引起的。

随着系统处理核的⽇益增加,可能导致消息传递作为 IPC 的⾸选机制。

共享内存系统采⽤共享内存的进程间通信,需要通信进程建⽴共享内存区域。

通常,这⼀⽚共享内存区域驻留在创建共享内存段的进程地址空间内。

其它希望使⽤这个共享内存段进⾏通信的进程应将其附加到⾃⼰的地址空间。

回忆⼀下,通常操作系统试图阻⽌⼀个进程访问另⼀个进程的内存。

共享内存需要两个或更多的进程同意取消这⼀限制;这样它们通过在共享区域内读出或写⼊来交换信息。

数据的类型或位置取决于这些进程,⽽不是受控于操作系统。

另外,进程负责确保,它们不向同⼀位置同时写⼊数据。

进程间通信常见方法

进程间通信常见方法

进程间通信常见方法
进程间通信是操作系统中的重要概念,它涉及不同进程之间的数据传输和信息
共享。

在现代操作系统中,常见的进程间通信方法包括以下几种:
1. 管道:管道是最简单的进程间通信方法之一,适用于具有父子进程关系的进程。

它通过创建一个管道,将一个进程的输出连接到另一个进程的输入,实现它们之间的数据传输。

2. 消息队列:消息队列是一种以消息为单位进行进程间通信的方法。

它通过创
建一个消息队列,进程可以向队列中发送消息,并由其他进程接收。

这种通信方式可以实现进程之间的异步通信,提供了较大的灵活性。

3. 共享内存:共享内存是一种高效的进程间通信方法,它允许多个进程访问同
一块物理内存。

通过映射同一块共享内存区域到不同的进程地址空间,进程可以直接读写共享内存中的数据,实现高速的数据交换。

4. 套接字(Socket):套接字是一种用于网络编程的通信机制,也可以在本地
进程间进行通信。

它提供了一种可靠的、面向连接的方式来实现进程间的数据传输。

通过使用套接字,进程可以在不同主机或同一主机的不同进程之间进行通信。

这些是常见的进程间通信方法,每种方法都有其适用的场景和特点。

在实际应
用中,我们可以根据具体需求选择合适的通信方法来实现进程间的数据传输和信息共享。

了解这些通信方法的特点和使用方式,对于处理多进程间的数据交互是非常重要的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、剪贴板1、基础知识剪贴板实际上是系统维护管理的一块内存区域,当在一个进程中复制数据时,是将这个数据放到该块内存区域中,当在另一个进程中粘贴数据时,是从该内存区域中取出数据。

2、函数说明:(1)、BOOL OpenClipboard( )CWnd类的OpenClipboard函数用于打开剪贴板。

若打开剪贴板成功,则返回非0值。

若其他程序或当前窗口已经打开了剪贴板,则该函数返回0值,表示打开失败。

若某个程序已经打开了剪贴板,则其他应用程序将不能修改剪贴板,直到前者调用了CloseClipboard函数。

(2)、BOOL EmptyClipboard(void)EmptyClipboard函数将清空剪贴板,并释放剪贴板中数据的句柄,然后将剪贴板的所有权分配给当前打开剪贴板的窗口。

(3)、HANDLE SetClipboardData(UINT uFormat, HANDLE hMem)SetClipboardData函数是以指定的剪贴板格式向剪贴板上放置数据。

uFormat指定剪贴板格式,这个格式可以是已注册的格式,或是任一种标准的剪贴板格式。

CF_TEXT表示文本格式,表示每行数据以回车换行(0x0a0x0d)终止,空字符作为数据的结尾。

hMem指定具有指定格式的数据的句柄。

hMem参数可以是NULL,指示采用延迟提交技术,则该程序必须处理WM_RENDERFORMA T和WM_RENDERALLFORMATS消息。

应用程序在调用SetClipboardData函数之后,就拥有了hMem参数所标识的数据对象,该应用程序可以读取该数据对象,但在应用程序调用CloseClipboard函数之前,它不能释放该对象的句柄,或者锁定这个句柄。

若hMem标识了一个内存对象,那么这个对象必须是利用GMEM_MOVEABLE标志调用GlobalAlloc函数为其分配内存。

注意:调用SetClipboardData函数的程序必须是剪贴板的拥有者,且在这之前已经打开了剪贴板。

延迟提交技术:当一个提供数据的进程创建了剪贴板数据之后,直到其他进程获取剪贴板数据之前,这些数据都要占据内存空间。

若在剪贴板上放置的数据过大,就会浪费内存空间,降低对资源的利用率。

为了避免这种浪费,就可以采用延迟提交计数,也就是由数据提供进程先提供一个指定格式的空剪贴板数据块,即把SetClipboardData函数的hMem参数设置为NULL。

当需要获取数据的进程想要从剪贴板上得到数据时,操作系统会向数据提供进程发送WM_RENDERFORMA T消息,而数据提供进程可以响应这个消息,并在此消息的响应函数中,再一次调用SetClipboardData函数,将实际的数据放到剪贴板上。

当再次调用SetClipboardData函数时,就不再需要调用OpenClipboard函数,也不再需要调用EmptyClipboard函数。

也就是说,为了提高资源利用率,避免浪费内存空间,可以采用延迟提交技术。

第一次调用SetClipboardData函数时,将其hMem参数设置为NULL,在剪贴板上以指定的剪贴板格式放置一个空剪贴板数据块。

然后直到有其他进程需要数据或自身进程需要终止运行时再次调用SetClipboardData函数,这时才真正提交数据。

(4)、HGLOBAL GlobalAlloc( UINT uFlags,SIZE_T dwBytes);GlobalAlloc函数从堆上分配指定数目的字节。

uFlags是一个标记,用来指定分配内存的方式,uFlags为0,则该标记就是默认的GMEM_FIXED。

dwBytes指定分配的字节数。

存中从来不被移动,但可在一个默认堆中被移动。

创建一个进程时,系统为应用程序分配一块默认堆。

返回值是一块内存对象句柄,若想将这个句柄转换为一个指针,可以使用GlobalLock函数。

这个标志不能和GMEM_FIXED标志一起使用。

GMEM_ZEROINIT 初始化内存的内容为0GPTR GMEM_FIXED和GMEM_ZEROINIT的组合(5)、LPVOID GlobalLock(HGLOBAL hMem);GlobalLock函数是对全局内存对象加锁,然后返回该对象内存块第一个字节的指针。

hMem 指一个全局内存对象句柄。

每个内存对象的内部数据结构中都包含了一个初始值为0的锁计数,对于可移动的内存对象来说,GlobalLock函数将其锁计数加1,而GlobalUnlock函数将锁计数减1。

被锁定的内存对象的内存块将保持锁定,直到它的锁计数为0,这时,该内存块才能被移动,或者被废弃。

另外,已被加锁的内存不能被移动,或者被废弃,除非调用了GlobalRealloc函数重新分配了该内存对象。

对于一个进程来说,每一次调用GlobalLock函数后,最后一定要记住调用GlobalUnlock函数。

使用GMEM_FIXED标志分配的内存对象其锁计数总是0。

GMEM_FIXED与GMEM_MOVEABLE标志的区别:若指定的是前者,那么GlobalAlloc函数返回的句柄值就是分配的内存地址;若指定的是后者,那么GlobalAlloc 函数返回的不是实际内存的地址,而是指向该进程中句柄表条目的指针,该条目中包含有实际分配的内存指针。

若一个函数的返回值为HGLOBAL类型,那么我们应该假定它的内存是采用GMEM_MOVEABLE标志来分配的,这就意味值必须调用GlobalLock函数对该全局内存对象加锁,并且返回该内存的地址。

若一个函数的参数类型为HGLOBAL,我们就应该用GMEM_MOVEABLE标志调用GlobalAlloc函数来生成这个参数值。

3、实例讲解,利用剪贴板实现通信(1)、新建一个基于对话框的MFC程序Clipboard,设计ID为IDD_CLIPBOARD_DIALOG 的对话框资源如下:(2)、为Send按钮添加单击命令响应函数,将发送编辑框中的内容发送到剪贴板:void CClipboardDlg::OnBtnSend(){if(OpenClipboard()){//打开剪贴板成功CString str;//用于保存发送编辑框中的数据HANDLE hClip;//用于保存GlobalAlloc函数分配的内存对象的句柄char *pBuf;//用于保存调用GlobalLock函数后返回的内存地址EmptyClipboard();//清空剪贴板,并获得剪贴板所有权GetDlgItemText(IDC_EDIT_SEND,str);//将发生编辑框中的数据保存到strhClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//分配内存对象,若设定的是文本数据,那么该数据是以空字符结尾,所以多分配一个字节pBuf=(char*)GlobalLock(hClip);//对内存对象加锁,将句柄转换为指针strcpy(pBuf,str);//将str中的数据复制到pBuf指向的内存中GlobalUnlock(hClip);//对内存块解锁SetClipboardData(CF_TEXT,hClip);\\向剪贴板上放置数据CloseClipboard();//关闭剪贴板}}注意:在把数据放置到剪贴板之后,一定要记得调用CloseClipboard函数关闭剪贴板,否则其他进程将无法打开剪贴板。

(3)、为Recv按钮添加单击命令响应函数,从剪贴板上取出数据显示到接受编辑框中:void CClipboardDlg::OnBtnRecv(){if (OpenClipboard()){//打开剪贴板成功if (IsClipboardFormatAvailable(CF_TEXT)){//若剪贴板中的数据是CF_TEXT格式的数据HANDLE hClip;char *pBuf;hClip=GetClipboardData(CF_TEXT);//返回CF_TEXT格式存在的剪贴板对象的句柄pBuf=(char*)GlobalLock(hClip);GlobalUnlock(hClip);SetDlgItemText(IDC_EDIT_RECV,pBuf);}CloseClipboard();}}二、匿名管道1、基础知识匿名管道是一个未命名的单向管道,通常用来在一个父进程和一个子进程之间传输数据。

匿名管道只能实现本地机器上两个父子进程间的通信,而不能实现跨网络的通信。

另外,利用匿名管道还可以实现同一个进程内数据的读取和写入。

2、函数说明(1)、BOOL CreatePipe(PHANDLE hReadPipe,PHANDLE hWritePipe,LPSECURITY_ATTRIBUTES lpPipeAttributes,DWORD nSize)CreatePipe创建一个匿名管道。

hReadPipe返回管道的读取句柄,hWritePipe返回管道的写入句柄。

lpPipeAttributes指向SECURITY_ATTRIBUTES结构体的指针,检测返回的句柄是否能被子进程继承,若此参数为NULL,则句柄不能被继承。

nSize指定管道的缓冲区大小,该大小仅仅是一个建议值,系统将使用该值计算一个适当的缓冲区大小,若此参数为0,系统则使用默认的缓冲区大小。

(2)、typedef struct _SECURITY_A TTRIBUTES {DWORD nLength;LPVOID lpSecurityDescriptor;BOOL bInheritHandle;} SECURITY_ATTRIBUTES, *PSECURITY_A TTRIBUTES;SECURITY_ATTRIBUTES结构体的nLength指定该结构体的大小。

lpSecurityDescriptor指向安全描述符的指针,若该参数为NULL,则系统为创建的匿名管道赋予默认的安全描述符。

bInheritHandle指定所返回的句柄是否能被一个新的进程所继承,若该参数设为TRUE,则返回的句柄能被新进程继承。

(3)、BOOL CreateProcess(LPCTSTR lpApplicationName,LPTSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCTSTR lpCurrentDirectory,LPSTARTUPINFO lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation );CreateProcess创建一个进程。

相关文档
最新文档