多进程之间的通讯

1.管道

创建管道的系统调用pipe,管道也是父进程和子进程间通讯的常用手段。管道能在父、子进程间传递数据,利用的是fork调用之后两个管道文件描述符(fd[0]和fd[1])都保持打开。一对这样的文件描述符只能保证父子进程间一个方向的数据传输,父进程和子进程必须有一个关闭fd[0],另一个关闭fd[1]。比如,我们要使用管道实现从父进程向子进程写数据。

     显然,如果要实现父、子进程之间的双向数据传输,就必须使用两个管道。socket编程接口提供了一个全双工的编程接口。管道只能用于两个有关联的进程(父子进程)间的通讯 

2.信号量

信号量是用于进程之间对临界资源的访问解决进程间同步问题,确保在任意时间段上只有一个进程可拥有对资源的独占访问。

信号量是一种特殊的变量,它取自然数值并且支持两种操作:等待和信号。对信号量的这两种操作常用的称呼为P操作,V操作。

P操作:如果信号量的值大于0,就将它减1.如果信号量的值为0,则将进程挂起。

V操作:如果信号量的值为0,就将它加1.如果有其他进程因为等待信号量而被挂起,则将该进程唤醒。

semget函数用于创造一个新的信号量集,或获取一个已存在信号量集。

#include<sys/sem.h>
int semget(key_t,int num_sems,int sem_flags);key是一个键值,用来标识全局唯一的一个信号量集。
sem_flags参数指定一组标识。
num_sems是信号量集中信号量的个数。
semop系统函数,系统调用改变信号量的值,即进行P,V操作。
int semop(int sem_id,struct sembuf* sem_op,size_t num_sem_ops);
sem_id参数是由semget调用返回的信号量集标识符,用以指定被操作的信号量集。
num_sem_ops指定要执行的操作个数,即sem_op中元素的个数。
semctl系统调用函数,semctl函数允许调用者直接对信号量进行直接控制。
int semctl(int sem_id,int sem_num,int command);

sem_id参数是由semget调用返回的信号量集的标识符。用以被指定的信号量集。

sem_num参数指定被操作的信号量在信号量中的编号。command参数指定要执行的命令。

3.共享内存

共享内存是最高效的IPC机制,因为它不涉及进程间任何的数据传输。但我们必须采取其他辅助手段来同步进程对共享内存的访问。不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内存连接到他们自己的地址空间中,所有的进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。

多进程编程 java 多进程编程接口_信号量

shamget系统调用创建一段新的共享内存,或者获取一段已经存在的一段已经存在的共享内存。

int shmget(key_t,size_t size,int shmflg);

shmget 函数返回一个整形值,表示共享内存的标识符。shmget返回失败时返回-1,并设置error。

共享内存被创建后我们不能立即访问它,首先需要将它关联到进程的地址空间中。适用完共享内存后,我们也要将它从进程地址空间中分离。

void * shmat(int shm_id,const void *shm_addr,int shmflg);
int shmdt(const void *shm_addr);

其中,shm_id参数是由shmget调用返回的共享内存标识符。shm_addr参数指定将共享内存关联到进程的哪块地址空间上,最终还是要受到shmflg参数的可选标志SHM_RND的影响。shmat成功时返回共享内存被关联到的地址,失败则返回(void*)-1并设置error。

shmdt函数是将共享内存从内存地址中分离。成功时返回0,失败返回-1,并设置error。

shmctl系统函数调用控制共享内存的某些属性。

int shmctl(int shm_id,int command,struct shmid_ds *buf);

 

4.消息队列:

消息队列是在两个进程之间传递二进制块数据的一种简单有效的方式。每个数据块都有一个特定的类型,接收方可以根据类型来有选择的接收数据,而不一定要像管道和命名管道那样必须以先进先出的方式接收数据。

msgget系统函数调用创建了一个消息队列,或者获取一个已有的消息队列。和semget系统函数调用一样,key参数是一个键值,用来标识一个全局唯一的一的消息队列。

msmget成功时返回一个正型值它是一个消息队列的标识符。失败返回-1.

msgsnd系统函数调用将一条消息添加到消息对列中,

msgrcv系统调用从消息队列中获取消息。

msgctl系统调用控制消息队列中的某些属性。