进程间通信(IPC),是为了在多个进程间交互信息。Linux下,线程可看作特殊进程。
常用IPC方式有:管道(pipe, fifo)、消息队列、共享内存、socket。进程间交互信息,通常需要同步(同步与锁 )。
常用特性总结
管道pipe
函数声明:int pipe(int fd[2]); 其中fd[0]只能读,fd[1]只能写。用于父子/兄弟进程间的通信。随进程持续。
pipe是半双工通信(数据只能从一端流向另一端,即fd[0]只能读,fd[1]只能写)。
fork后,子进程的fd是父进程的副本。
只能从头开始读数据,不能用lseek。
当读的一端close后,写的一端继续写,操作系统会给写进程发送SIGPIPE信号。
管道fifo
函数声明: int mkfifo(const char* pathname, int mode);进程间通过pathname来共享同一个fifo。
fifo是双工通信(数据可以在fifo两端流动)。可用于无亲缘关系的进程间通信。随进程持续。
只能从头开始读数据,不能用lseek。
当读的一端close后,写的一端继续写,操作系统会给写进程发送SIGPIPE信号。
Posix消息队列
消息队列可看作是消息链表,同时消息队列具有权限,只有拥有足够权限的进程才可以读/写消息队列。消息队
列
随内核持续。
使用"man 7 mq_overview",查看消息队列需要注意的信息。
1.消息队列属性
(1)持续性:消息队列随内核持续
(2)父子进程间:子进程继承父进程消息队列描述符,这些描述符与父进程指向相同的消息队列。
(3)优先级[0 ~ _SC_MQ_PRIO_MAX-1]:高优先级的消息,总是优先被传递。
(4)mq_unlink的作用:消息队列有引用计数,当mq_open时,+1;当mq_close时,-1;当进程退出时,-1;当计数为0时,mq_unlink才起作用,将消息队列真正的删除(无论消息队列中是否还有消息没有被取出)。
2.常用函数
(1)mq_open, mq_close, mq_unlink
(2)mq_getattr, mq_setattr
(3)mq_send, mq_receive
(4)mq_notify
3.注意事项
(1)队列的命名格式必须为 "/xxx",中间不能有多级的"/"。
(2)需要执行命令:
mkdir /dev/mqueue;
mount -t mqueue none /dev/mqueue。消息队列创建在虚拟文件系统上(message queues are created in a virtual file system),需要先挂载文件系统。
(3)编译时,需要加上“
-lrt”库。
(4)消息队列是有大小限制的,当队列满时,mq_send会阻塞;当消息队列空时,mq_receive会阻塞。
(5)执行完mq_open后,可以在“/dev/mqueue/”目录下,看到消息队列。可以使用“cat /dev/mqueue/XX”查看消息队列的情况(QSIZE:50 NOTIFY:0 SIGNO:0 NOTIFY_PID:0)。
Posix共享内存
共享内存中的数据不经过内核,所以是最快的IPC。但需要同步(
同步与锁)。
阅读(2634) | 评论(0) | 转发(0) |