进程间通讯有以下几种:管道、消息队列、信号量、内存共享
一、消息队列
消息: 数据 & 类型
队列: 先进先出 优先级队列
消息队列:发送带有类型的数据,读数据的进程可以根据类型获取特定的数据,并且在这一类型上遵循先进先出。
具体操作:
Linux提供了一系列消息队列的函数接口来让我们方便地使用它来实现进程间的通信。它的用法与其他两个System V PIC机制,即信号量和共享内存相似。
1、msgget函数:该函数用来创建和访问一个消息队列。它的原型为:
int msgget((key_t)key, int msgflg);
它返回一个以key命名的消息队列的标识符(非零整数),失败时返回-1
2、msgsnd函数:该函数用来把消息添加到消息队列中。它的原型为:
int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
如果调用成功,消息数据的一分副本将被放到消息队列中,并返回0,失败时返回-1
3、msgrcv函数:该函数用来从一个消息队列获取消息,它的原型为:
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
调用成功时,该函数返回放到接收缓存区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息。失败时返回-1
4、msgctl函数:该函数用来控制消息队列,它与共享内存的shmctl函数相似,它的原型为:
int msgctl(int msgid, int command, struct msgid_ds *buf);
成功时返回0,失败时返回-1.
二、信号量
信号量有关的知识:
1、原子操作:不可中断的操作,一旦操作开始执行,就不能停止,直到其运行完成
2、临界资源:在同一时刻,只能被一个进程访问的资源。
3、临界区:在程序中,访问临界资源的代码区域
4、进程同步:说到同步,好多人会觉得是同时,其实恰恰相反,进程同步指的是一个进程需要等待另一个进程的某些条件的发生,才能接着运行,它们之间是一种合作的关系,就如同接力棒比赛,第一个人跑完到第二个人的位置后,第二个人才能跑起来,在这之前,第二个人只能等待,其他什么都干不了。
5、进程异步:两个或两个以上进程互不干涉,相互无影响,是独立执行的个体
6、信号量:信号量是做进程间同步控制的一种记录资源数量的一个计数器。它是一个特殊的变量,只能取正整数值,并且程序对其访问只能进行原子操作;一个更正式的定义是信号量是一个特殊的变量,只能对它进行等待(wait)和发送信号(signal)两种操作,在linux中,将P(信号量变量)用于等待,V(信号量变量)用于发送信号。
P(sv) 如果sv的值大于0,就给sv减去1,;如果sv的值等于0,就挂起该进程的执行。
V(sv) 如果有其他进程因等待sv而被挂起,就让它恢复运行;如果没有,就给sv加1。
注:sv:信号量
具体操作:
1、semget函数的作用是创建一个新信号量或得到一个已有信号量的键
int semget((key_t)key, int nums, int flag);
注:nums创建时,指定信号量集中信号量的个数(数组的大小),一般都取1。
2、semctl函数用来直接控制信号量信息
int semctl(int semid, int num, int cmd, );
3、semop函数用于改变信号量的值,一次性操作,p v操作都需要它,第二个参数就是个结构体指针,其中sem_op成员就是控制具体让信号量加1还是减1,加1就设置为1,减1就设为-1
int semop(int semid, struct sembuf * buff, int len);