0、章节引用
1、课堂目标
- 进程间通信方式介绍(了解)
- 无名管道特点(理解)
- 无名管道创建(熟练)
- 小结
2、进程间通信介绍
- 从早期UNIX继承的进程间通信方式
- 1、无名管道(pipe)
- 2、有名管道(fifo)
- 3、信号(signal)
- 贝尔实验室改进的System V IPC
- 1、共享内存(share memory)
- 2、消息队列(message quenue)
- 3、信号灯集(semaphore set)
- BSD(加州大学伯克利分校的伯
克利软件发布中心)开发的套接字(socket:可以本地之间通信,可以与别的主机通信)
3、无名管道
4、无名管道特点
- 无名管道具有的特点:
- 1、只有用于具有亲缘关系的进程之间的通信
-
- 创建后,没有路径,在文件中不可见,仅仅在内存中,无名管道是一个进程创建的,打开他的方法,只能通道继承的方法。
- 2、半双工的通信模式,具有固定的读端和写端
-
- 父进程若为写,子进程只能用于读。若想相互通信需要创建两个无名管道。
- 3、管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的 read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
5、无名管道创建(pipe)
#include
int pipe(int pfd(2));
- 成功返回0,失败返回EOF
- pfd包含两个元素的整形数组,用于存放文件描述符
- 固定pfd[0]用于读管道,pfd[1]用于写管道
6、无名管道通信
- 图中父进程为读端,子进程为写端,是一种通信,也可以父进程为写端,子进程为读端,但这两种只能选择一种。
7、无名管道-示例
- 子进程1和子进程2分别往管道中写入字符串,父进程读取管道数据内容并打印。
#include
#include
#include
#include
#include
#include
int main(void)
{
pid_t pid1,pid2;
char buf[32];
int pfd[2];
int read_num = 0;
if(pipe(pfd)<0)//创建管道
{
perror("pipe");
exit(-1);
}
if((pid1 = fork())<0)//创建子进程1
{
perror("fork");
exit(-1);
}
else if(pid1 == 0)//子进程1写入buf后退出
{
close(pfd[0]);//关闭读端
strcpy(buf,"process1");
if(write(pfd[1],buf,32)!= -1)
{
printf("success 1n");
}
close(pfd[1]);//关闭写端
exit(0);
}
else
{
if((pid2 = fork())<0)//创建子进程2
{
perror("fork");
exit(-1);
}
else if(pid2 == 0)//子进程2写入buf后退出
{
close(pfd[0]);//关闭读端
sleep(1);//延时,防止子进程1和子进程2同时写
strcpy(buf,"process2");
if(write(pfd[1],buf,32)!= -1)
{
printf("success 2n");
}
close(pfd[1]);//关闭写端
exit(0);
}
else
{
close(pfd[1]);//关闭写端
wait(NULL);//优先子进程
read_num = read(pfd[0],buf,32);
printf("%d numbers read from the pipe is %sn",read_num,buf);
wait(NULL);//优先子进程
read_num = read(pfd[0],buf,32);
printf("%d numbers read from the pipe is %sn",read_num,buf);
close(pfd[0]);//关闭读端
}
}
return 0;
}
success 1
32 numbers read from the pipe is process1
success 2
32 numbers read from the pipe is process2
8、无名管道小结
- 无名管道特征(使用范围、通信方式单工)
- pipe函数
欢迎关注微信工作号,推送文章更及时。