进程间的通信方式

参考链接:
http://blog.chinaunix.net/uid/26833883/cid-157153-list-1.html
linux下进程间通信的几种主要手段:

一、管道

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

A. 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
B. 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);
C. 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
D. 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1]。其中fd[0]固定用于读管道,而fd[1]固定用于写管道,一般文件I/O的函数都可以用来操作管道(lseek除外)。

二、有名管道

无名管道,由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道(FIFO)。

FIFO不同于无名管道之处在于它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据。值的注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。

注意:有名管道的名字存在于文件系统中,内容存放在内存中。

三、信号(进程间通信唯一的异步方式)

信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。

信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了那些系统事件。

如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递个它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞取消时才被传递给进程。

//linux操作系统支持的信号
kill  -l

system v IPC对象

IPC:Inter-Process Communication
在IPC的通信模式下,不管是使用消息队列还是共享内存,甚至是信号灯,每个IPC的对象都有唯一的名字,称为”键”(key)。通过”键”,进程能够识别所用的对象。”键”与IPC对象的关系就如同文件名称于文件,通过文件名,进程能够读写文件内的数据,甚至多个进程能够公用一个文件。而在 IPC的通讯模式下,通过”键”的使用也使得一个IPC对象能为多个进程所共用。

四、共享内存

共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

共享内存的介绍

  1. 共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。

  2. 为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率。

  3. 由于多个进程共享一段内存,因此也需要依靠某种同步机制。

共享内存的操作流程

  1. 创建/打开共享内存
  2. 映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
  3. 撤销共享内存映射
  4. 删除共享内存对象
五、消息队列

报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息

函数:

1.创建新消息队列或取得已存在消息队列
原型:int msgget(key_t key, int msgflg);

参数:

 key:可以认为是一个端口号,也可以由函数ftok生成。
 msgflg:IPC_CREAT值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。
 IPC_EXCL值,若没有该队列,则返回-1;若已存在,则返回0。

2.向队列读/写消息
原型:

msgrcv从队列中取用消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

msgsnd将数据放到消息队列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:

 msqid:消息队列的标识码
 msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下: 
struct msgstru{
    long mtype; //大于0
    char mtext[512];
};
 msgsz:消息的大小。
 msgtyp:从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。
 msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。如果msgflg和常数IPC_NOWAIT合用,则在msgsnd()执行时若是消息队列已满,则msgsnd()将不会阻塞,而会立即返回-1,如果执行的是msgrcv(),则在消息队列呈空时,不做等待马上返回-1,并设定错误码为ENOMSG。当msgflg为0时,msgsnd()及msgrcv()在队列呈满或呈空的情形时,采取阻塞等待的处理模式。

3.设置消息队列属性
原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

参数:msgctl 系统调用对 msgqid 标识的消息队列执行 cmd 操作,系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID

IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET : 该命令用来设置消息队列的属性,要设置的属性存储在buf中。     
IPC_RMID : 从内核中删除 msqid 标识的消息队列。
六、信号量semaphore

信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。

Linux支持System V的信号量(semaphore),是一种进程间通信的方式,只不过它和管道、FIFO或者共享内存不一样,信号量主要用于同步或者互斥对共享资源的访问,它的发明来源于火车运行系统中的”信号灯”,利用信号量可以实现”PV”操作这种进程间同步进制。P操作时获得资源,将信号量的值减1,如果结果不为负则执行完毕,进程获得资源,否则进程睡眠以等待的进程释放;V操作则是释放资源,给信号量的值加1, 唤醒一个因执行P操作而等待的进程。

信号量的两种类型

A、二值信号量

最简单的信号量形式,信号量的值只能取0或1,类似互斥锁。

注意:虽然二值信号量能够实现互斥锁的功能,但两者的关注内容不同。信号量调共享资源,只要共享资源可用,其他进程同样可以修改信号量的值;互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁。

B.计数信号量

信号量的值可以取任意非负值(当然受内核本省的约束),用来统计资源,其值就代表可用资源的个数。

注意:通常所说的系统V信号量指的是计数信号量集

七、套接字Socket

套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值