进程间通信
- 早期unix进程间通信
无名管道(pipe)
有名管道(fifo)
信号(signal) - system V IPC
共享内存(share momeory)
消息队列(message queue)
信号灯集(semaphore set) - 套接字(socket)
无名管道(pipe)
pipe特点
- 只能用于具有亲缘关系的进程之间的通信
- 单工通信模式,读端 和写端固定
- pipe仅仅在内存中存在,不像文件一样有路径可以访问
- 要想打开其它进程创建的pipe,唯一的方法是通过继承的方式
pipe的创建
#include <unistd.h>
int pipe(int pfg[2]);
//success 0 failed error code
//pfd 包含两个元素的整型数组,用来保存文件描述符
//pfd[0]用于读管道,pfd[1]用于写管道
//管道中的数据读走了之后就空了,没有了
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid1,pid2;
char buf[32];
int pfd[2];
if(pipe(pfd) < 0){
perror("pipe");exit(-1);
}
if((pid1 = fork()) < 0){
perror("fork");exit(-1);
}else if(pid1 == 0){//subprocess1
strcpy(buf,"I'm process1");
write(pfd[1],buf,32);
exit(0);
}else{//process
if((pid2 = fork()) < 0){
perror("fork");exit(-1);
}else if(pid2 == 0){//subprocess2
sleep(1);
strcpy(buf,"I'm process2");
write(pfd[1],buf,32);
}else{//process
wait(NULL);
read(pfd[0],buf,32);
printf("%s\n",buf);
wait(NULL);
read(pfd[0],buf,32);
printf("%s\n",buf);
}
}
return 0;
}
读pipe
- 写端存在
有数据 read返回实际读取的字节数
无数据 read阻塞,直到有数据可以读取 - 写端不存在
有数据 read返回实际读取的字节数
无数据 read 返回0,不阻塞
写pipe
- 读端存在
有空间 write返回实际写入的字节数
无空间 进程写阻塞,直到有其它进程将数据读走,有空间可以写入
(可以用于测试pipe大小) - 读端不存在
管道断裂,被信号结束
验证管道断裂
子进程写管道
父进程回收,查看回收返回状态
#include <stdio.h>
#include <stdlib.h>
#include <uinstd.h>
#include <sys/wait.h>
int main(){
pid_t pid;
int pfd[2],status;
char buf[32];
if(piipe(pfd) < 0){
perror("pipe");exit(-1);
}
close(pfd[0]);
if((pid = fork()) < 0){
perror("fork");exit(-1);
}else if(pid == 0){
write(pfd[1],buf,32);
exit(0);
}else{
wait(&status);
printf("status = %d\n",status);
}
}
信号值13:SIGPIPE代表管道断裂
L5-D4