同一个主机的进程间通信:
- 无名管道(PIPE)——适用与任何同主机进程(多亲缘关系进程)——管道是单向的,多进程使用同一管道会产生交叉读写的问题
- 有名管道(FIFO)——依赖文件系统,实现不同进程对文件系统下某个文件的访问
- 消息队列(Message Queue)——同主机任意多进程间通信——存放的数据量有限,适用与少量数据传递
- 共享内存(Share Memory)——同主机任意进程间大量数据通信——数据访问存在竞争问题
- 信号(Signal)——同主机进程间同步机制
- 信号量(semaphore)——同主机进程间异步机制
网络主机间进程通信:
- RPC
- 套接口(Socket)
有名管道和普通文件一样具有磁盘路径,文件权限等属性,但是有名管道并没又在磁盘中存放真正的信息,他存放的通信信息在内存中,两个进程结束后丢失
创建有名管道:
mkfifo(要创建的管道文件名,生成文件的模式)
该文件必须不存在
读写有名管道:
先open()打开文件,在readI()/write()
如果以某种方式打开有名管道,那么系统将阻塞,知道另一进程以另一种方式打开管道才会继续执行
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <fcntl.h> 4 #include <signal.h> 5 #include <sys/types.h> 6 7 void handler(int sig) 8 { 9 printf("sig=%d\n",sig); 10 } 11 12 int main(void) 13 { 14 int j; 15 signal(SIGPIPE,handler);//设置某一信号的对应动作,第一个指所要处理的信号类型,handler描述了与信号关联的动作,当接收到一个类型为sig的信号时,就执行handler 所指定的函数 16 unlink("FIFO");//删除原来的管道 17 mkfifo("FIFO",0644); 18 pid_t pid; 19 pid=fork(); 20 if(pid==0) 21 { 22 int fd; 23 fd=open("FIFO",O_RDONLY); 24 close(fd); 25 } 26 else 27 { 28 int fd; 29 fd=open("FIFP",O_WRONLY); 30 int ret; 31 sleep(1); 32 ret=write(fd,"helloworld",10); 33 printf("ret=%d\n",ret); 34 } 35 }
非亲源渐进成使用有名管道通信:
发送数据write
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <fcntl.h> 5 #include <string.h> 6 #include <limits.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 10 #define FIFO_NAME "/tmp/my_fifo" 11 12 int main(int argc,char* argv[]) 13 { 14 int pipe_fd; 15 int res; 16 char buffer[]="hello world!"; 17 if(access(FIFO_NAME,F_OK)==-1)//文件是否存在,不存在才能创建有名管道 18 { 19 res=mkfifo(FIFO_NAME,0766); 20 if(res!=0) 21 { 22 fprintf(stderr,"could not creat fifo %s\n",FIFO_NAME); 23 exit(EXIT_FAILURE); 24 } 25 } 26 printf("process %d opening FIFO O_WRONLY\n",getpid()); 27 pipe_fd=open(FIFO_NAME,O_WRONLY);//以只写的方式打开有名管道 28 printf("the file's description is %d\n",pipe_fd); 29 if(pipe_fd!=-1) 30 { 31 res=write(pipe_fd,buffer,sizeof(buffer)); 32 if(res==-1) 33 { 34 fprintf(stderr,"write error on pipe\n"); 35 exit(EXIT_FAILURE); 36 } 37 printf("write data is %s,%d bytes is write\n",buffer,res); 38 close(pipe_fd); 39 } 40 else 41 exit(EXIT_FAILURE); 42 printf("process %d finished\n",getpid()); 43 exit(EXIT_FAILURE); 44 }
[root@sun fifo]# ./not_parent_task_write
process 3356 opening FIFO O_WRONLY //阻塞,等待read
the file's description is 3 //read执行后出现
write data is hello world!,13 bytes is write
process 3356 finished
读取数据read
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <string.h> 5 #include <fcntl.h> 6 #include <limits.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 10 #define FIFO_NAME "/tmp/my_fifo" 11 12 int main(int argc,char* argv[]) 13 { 14 int pipe_fd; 15 int res; 16 char buffer[4096]; 17 int bytes_read=0; 18 memset(buffer,'\0',sizeof(buffer)); 19 printf("process %d opening FIFO O_RDONLY\n",getpid()); 20 pipe_fd=open(FIFO_NAME,O_RDONLY); 21 printf("the file's description is %d\n",pipe_fd); 22 if(pipe_fd!=-1) 23 { 24 bytes_read=read(pipe_fd,buffer,sizeof(buffer)); 25 printf("the read data is %s\n",buffer); 26 close(pipe_fd); 27 } 28 else 29 exit(EXIT_FAILURE); 30 printf("process %d finished,%d bytes read\n",getpid(),bytes_read); 31 exit(EXIT_FAILURE); 32 }
[root@sun fifo]# ./not_parent_task_read
process 3393 opening FIFO O_RDONLY
the file's description is 3
the read data is hello world!
process 3393 finished,13 bytes read