IPC:Inter-process Communication 进程间通信
缘由:
1、数据传输:进程间有数据互相传输的需求
2、通知事件:一个进程需要向另一个或一组进程发送消息,通知某种事件的发生(如进程终止时要通知父进程)。
3、资源共享:多个进程之间共享同样的资源。对共享数据的修改,其他进程应该立刻看到,需要内核提供锁和同步机制。
4、进程控制:有些进程希望完全控制另一个进程的执行,如Debug进程。
起源
主要的IPC方式:
管道、消息队列、信号、共享内存、内存映射、信号量、套接字
每种方式都有各自的优缺点。
管道(pipe)
管道(pipe),包括两种方式:
A、普通pipe可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
实现:int pipe(int fd[2]);
说明: pipe()会建立管道,并将文件描述词由参数filedes数组返回。filedes[0]为管道里的读取端,filedes[1]则为管道的写入端。
两个父子进程的管道通信:
父进程关闭管道的读,子进程关闭管道的写。
父进程关闭管道1的读,管道2的写;子进程关闭管道2的读,管道1的写
B、命名管道(named pipe,FIFO):命名管道除了具有普通pipe的功能(也是半双工),它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。
实现:int mkfifo(const char *pathname,mode_tmode);(mkfifo命令也行)
信号
signal,信号是比较复杂的通信方式,用于通知接收进程有某种事件发生了,除了进程间通信外,进程还可以发送信号给进程本身;
实现:使用系统底层的信号机制,signal函数,kill函数
消息队列
消息队列是消息的链接表。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺陷。
实现:int msgget(key_t key,int msgflg);
共享内存:
申请一块内存,某进程往共享内存中写,其他的进程就可以通过读出共享内存中的内容来获取该进程所传送的信息,是最快的可用IPC形式。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
实现:int shmget(key_t key,size_t size,intshmflag);
内存映射
内存映射允许任何多个进程间通信,每一个使用该机制的进程通过虚拟内存把一个共享的文件映射到自己的进程地址空间来实现它。
实现
void *mmap(void *addr, size_t len, int prot, int flag, int filedes,off_t off);
信号量
semaphore,主要作为进程间、同一进程不同线程间的同步手段,通过PV操作实现。
实现
int semget(key_t key,int num_sems,int sem_flgs); 创建一个信号量或获取一个已知信号量的键
套接字
socket,更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
实现:通过socket的TCP连接实现,C/S架构。
参考:http://www.ibm.com/developerworks/cn/linux/l-ipc/
http://www.cnblogs.com/xiazh/archive/2012/11/08/2757882.html