进程间通讯(IPC,InterProcess Communication)是指在不一样进程之间传播或交换信息。进程间通讯的方式有以下几种:html
特色:node
管道只容许具备血缘关系的进程间通讯,如父子进程间的通讯。ios
管道并不是是进程全部的资源,而是和套接字同样,归操做系统全部。能够将它当作文件系统,但该文件系统只存在于内存当中。c++
原型数组
#include <unistd.h> /* Create a one-way communication channel (pipe). If successful, two file descriptors are stored in PIPEDES; bytes written on PIPEDES[1] can be read from PIPEDES[0]. Returns 0 if successful, -1 if not. */ extern int pipe (int fd[2]) __THROW __wur;
参数的说明:函数
字符数组fd是管道传输或者接收时用到的文件描述符,其中fd[0]
是接收的时候使用的文件描述符,即管道出口;而fd[1]
是传输的时候用到的文件描述符,即管道入口。测试
为了使数据能够双向传递,可使用两个管道,一个管道负责进程1的写和进程2的读,另外一个管道负责一个进程1的读和进程2的写。测试程序以下:spa
#include <iostream> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #define BUF_SIZE 30 int main(){ int fds1[2], fds2[2]; /* *注意: * 此处不能写char* str1 = "Who are you?"; * 获得的sizeof(str1)等于8,该值其实是指针的大小,并非字符串数组的大小 * 这个时候要用strlen()函数(strlen的惟一标准是找‘\0’) * 系统函数返回值是char *(#include <string.h>)类型的每每会在末尾加上'\0'。 * 要注意的是未初始化的状况下,用strlen是不可行的 **/ char str1[] = "Who are you?"; char str2[] = "Thank you for your message."; char buf[BUF_SIZE]; pipe(fds1); //建立两个管道 pipe(fds2); pid_t pid = fork(); if(pid == 0){ write(fds1[1], str1, sizeof(str1)); read(fds2[0], buf, BUF_SIZE); printf("Child process copy the message: %s\n", buf); }else { read(fds1[0], buf, BUF_SIZE); printf("Parent Process copy the message: %s\n", buf); write(fds2[1], str2, sizeof(str2)); } return 0; }
2.FIFO操作系统
FIFO即命名管道,在磁盘上有对应的节点,但没有数据块—换言之,只是拥有一个名字和相应的访问权限,经过mknode()
系统调用或者mkfifo()
函数来创建的。一旦创建,任何进程均可以经过文件名将其打开和进行读写,而不局限于父子进程,固然前提是进程对FIFO有适当的访问权。当再也不被进程使用时,FIFO在内存中释放,但磁盘节点仍然存在。线程
/* Create a new FIFO named PATH, with permission bits MODE. */ extern int mkfifo (const char *__path, __mode_t __mode) __THROW __nonnull ((1));
其中的 mode 参数与open
函数中的 mode 相同。一旦建立了一个 FIFO,就能够用通常的文件I/O函数操做它。
当 open 一个FIFO时,是否设置非阻塞标志(O_NONBLOCK
)的区别:
O_NONBLOCK
(默认),以只读方式打开的FIFO要阻塞到其余的某个程序以写打开这个FIFO。一样以只写方式打开的FIFO要阻塞到其余某个进程以读方式打开该FIFO。O_NONBLOCK
,则以只读方式打开会马上返回而不阻塞(不是出错返回)。而以只写方式打开,若以前没有进程以读方式打开这个FIFO则马上出错返回。示例代码:一个进程发送消息给另外一个进程
writefifo.cpp
#include <iostream> #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> // O_WRONLY #include <time.h> //time #include <unistd.h> using namespace std; int main(){ int fd; int n; char buf[1024]; time_t tp; if( mkfifo("fifo1", 0666) < 0 && errno != EEXIST) //建立FIFO管道 { perror("Create FIFO Faileed"); } printf("I am %d process.\n", getpt()); //说明进程的ID if((fd = open("fifo1",O_WRONLY )) < 0){ //以只写方式打开FIFO perror("Open FIFO failed"); exit(1); } for (int i = 0; i < 10; ++i) { time(&tp); //获取当前系统时间 n = sprintf(buf, "Process %d's time is %s",getpid(), ctime(&tp)); printf("send message: %s", buf); if(write(fd, buf, n+1) < 0) { perror("write FIFO Failed"); close(fd); exit(1); } sleep(1); } close(fd); return 0; }
readfifo.cpp
#include <stdio.h> #include <iostream> #include <stdlib.h> #include <errno.h> #include <sys/stat.h> #include <fcntl.h> // O_WRONLY #include <time.h> //time #include <unistd.h> using namespace std; int main(){ int fd; int len; char buf[1024]; if((fd = open("fifo1", O_RDONLY)) < 0){ //以只读方式打开FIFO perror("Open FIFO failed"); exit(1); } while ((len = read(fd, buf ,1024)) > 0) //读取FIFO管道 { printf("Read message: %s", buf); } close(fd); return 0; }
若是在writefifo.cpp
中修改以下,设置非阻塞标志:
if((fd = open("fifo1",O_WRONLY | O_NONBLOCK)) < 0){ //以只写方式打开FIFO
若是先运行writefifo,在运行readfifo,则会出错。
3. 消息队列
消息队列,就是一个消息的链表,是一系列保存在内核的列表。用户进程能够向消息队列添加消息,也能够向消息队列读取消息。
特色:
4.共享内存
共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。
5. 信号量
信号量是一个计数器,能够用来控制多个进程对共享资源的访问。它常做为一种锁机制,防止某进程正在访问共享资源时,其余进程也访问该资源。所以,主要做为进程间以及同一进程内不一样线程之间的同步手段。
6.套接字
套解口也是一种进程间通讯机制,与其余通讯机制不一样的是,它可用于不一样及其间的进程通讯。