进程间通信总结
一、Linux实时性扩展
①锁会影响实时性;
②交互性进程一般都会被优先调度:因为每个进程都会有优先级,类似于等待键盘输入类的交互性进程,由于等待过程未运行,优先级不会变化;而其他进程的会执行使得优先级降低,从而使得交互性进程唤醒后的优先级较高被优先调度。
二、进程间的通信
①无名管道(pipe):
无名管道只能用于具有亲缘关系的进程之间的通信。属于半双工的通信模式,具有固定的读端和写端
无名管道的创建与关闭:
pipe:
fd为包含两个元素的整型数组;
返回值:成功返回0,出错返回-1。
使用实例:
结果:
程序说明已创建了管道连接子进程与父进程,父进程读到了子进程的内容。
注意:仅在读端存在的时候,写入才有意义。否则将收到内核传来的SIGPIPE信号,会杀死进程。
②有名管道(fifo):
可以使互不相关的两个进程互相通信,遵循先入先出的原则,但是不支持lseek()操作
mkfifo:
pathname:要创建的管道;
mode:创建的管道的访问权限。
使用实例:
结果:
③信号(signal)
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。
用户进程对信号的响应方式:
忽略信号:一般不会对SIGCHLD(子进程结束信号)做任何处理,但是SIGKILL和SIGSTOP信号不会被忽略。
发送与捕捉信号
kill:
raise:
pid:正数表示要接收信号的进程的进程号;0表示信号被发送到所有和pid进程在同一进程组的进程;-1表示信号发给所有的进表中的进程(除进程号最大的进程以外);
sig:需要发送的信号;
返回值:成功返回0,出错返回-1。
raise(sig)=kill(getpid(),sig)
使用实例:
结果为:
alarm与pause:
在特定的时候向自己发送一个SIGALARM信号,这个特定的时候有seconds决定;
pause用于将调用进程挂起,指导收到信号为止。
使用实例:
运行结果:
5s后:
信号的处理:
signal:
signum:指定的信号;
handler:SIG_IGN:忽略该信号;SIG_DFL:采用系统默认方式处理信号;使用函数自定义信号的处理方式。
返回值:成功:设置之前的信号处理方式,出错返回-1。
使用实例:使用signal实现子程序的自动回收(SIGCHLD的时候回收)
运行结果:
可以看出当signal收到SIGCHLD信号时执行了fun_child函数。
④System V IPC对象:
共享内存:
1)是最为高效的进程间通信方式,进程可以直接读内存而不需要任何数据的拷贝;
2)内核特意留有一块内存区,有需要访问的进程将其映射到自己的私有地址空间;
3)由于多个进程共享一段内存,因此需要考虑同步与互斥问题
共享内存的实现:
shmget:
key:IPC_PRICATE(key=0)或者ftok返回值(key=ftok(".",'a'));
size:共享内存区的大小;
shmflg:权限(8进制)
返回值:成功返回内存段标识符,失败返回-1。
结果:
使用ipcs -m查看:
说明共享内存已创建。
映射:
shmat:
shmid:需要映射的共享内存区标识符;
shmaddr:映射至指定的地址(通常为NULL表示系统自动完成映射);
shmflg:SHM_RDONLY:共享内存只读;一般为0,表示共享内存可读写;
返回值:成功返回映射后的地址;出错返回-1;
shmdt(解除映射):返回值:成功返回0,出错返回-1。
使用实例:
映射:
显示:
结果:
因为共享内存指定的地址为NULL,是由系统自行分配的,所以p的值会有可能不一样
shmctl:
cmd:主要掌握IPC_RMID(删除对象);
buf:一般为NULL;
返回值:成功返回0;出错返回-1
使用实例:
运行结果:
标识符为196612的共享内存被删除。
消息队列:消息队列是IPC对象的一种,可以按照类型来发送/接收消息
msgget:
key:与消息队列相关联的key值;
flag:消息队列的访问权限;
返回值:成功返回消息队列ID,出错返回-1。
msgsnd(类似write):
msqid:消息队列的ID;
msgp:指向消息的指针,常用结构体msgbuf
msgsz:发送消息正文的字节数;
msgflg:为0表示发送完成才返回;为IPC_NOWAIT表示没法送完全也会返回,不做等待;
返回值:成功返回0,出错返回-1。
msgrcv(类似read):
msgtype:0表示接收消息队列中第一个消息;大于0表示接收消息列表中第一个类型为msgtype的消息;小于0表示接收消息列表中类型不小于msgtype的绝对值且类型值有最小的消息;
返回值:成功返回接收到的消息的长度;失败返回-1。
msgctl:
与shmctl相似。
信号灯:又称作信号量,是不同进程间或一个给定进程内部不同线程间同步的机制
种类:posix有名信号灯;posix无名信号灯(基于内存的信号灯);System V信号灯(IPC对象)。
semget:
key:与信号灯集相关联的key值;
nsems:信号登记中包含的信号灯数目;
semflg:信号灯集的访问权限,通常为O_CREAT|0666;
返回值:成功返回信号灯集ID,出错返回-1.
semop:
semid:信号灯集ID
struct sembuf{
};
nops:要操作的信号灯的个数;
返回值:成功返回:0,出错返回-1。
semctl:
semnum:要修改的信号灯编号;
cmd:SETVAL:设置信号灯的值;IPC_RMID:从系统中删除信号灯的集合。
进程间通讯方式比较:
pipe:仅用于具有亲缘关系的进程间,单工,数据在内存中;
fifo:可用于任意进程间,双工,有文件名,数据在内存中;
signal:唯一的一部通信方式,模拟中断;
msg:常用于cs模式中,按消息类型访问,可有优先级;
shm:因为直接访问内存,所以效率是最高的,但是需要同步互斥机制;
sem:配合shm实现同步与互斥。