管道定义
- 能够连接读写进程, 并以生产消费关系通信的一个共享文件, 也称pipe文件
- 读进程从0 端读数据
- 写进程从1端写数据进入管道
管道类型
有名管道
- 在系统中长期存在的
- 有路径名的
- 使用open打开文件, 于正常文件打开方式一样
创建命名管道
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);
int mknod(const char *filename, mode_t mode | S_IFIFO, (dev_t)0)
无名管道
- 使用
pipe()
创建的无名文件(无路径名) - 即创建即用, 使用文件描述符标识访问
- 只有创建该pipe的进程及其子孙进程可用,
- 退出进程则pipe消失,核心回收索引节点
pipe文件的建立
分配磁盘和内存索引结点、为读进程分配文件表项、为写进程分配文文件表项, 分配用户文件描述符
要求读写进程互斥
每个进程在访问pipe文件前,需要检查该索引文件是否上锁
- 上锁 : 睡眠等待
- 不上锁 : 将其上锁, 进行读写, 操作结束后, 唤醒对应睡眠进程
代码示例
#include <stdlib.h>/*{{{*/
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
/*}}}*/
int pid1,pid2;
int main()
{
int fd[2];
char OutPipe[100],InPipe[100];
pipe(fd);
while(-1 == (pid1= fork()));
if (pid1 == 0)// in child process 1
{
/** int lockf(int fd, int cmd, off_t len); */
lockf(fd[1],1,0);// lock output file descriptor
/** write to the character string str. */
sprintf(OutPipe, "child 1 process is sengding message\n");
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{
while(-1 == (pid2 = fork()));
if(pid2 == 0)// in child process 2
{
lockf(fd[1],1,0);
sprintf(OutPipe, "child 2 process is sengding message\n") ;
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else// in parent process
{
wait(0);
printf("the follow is child process words\n");
read(fd[0],InPipe,50);
printf("%s\n",InPipe);
wait(0);
read(fd[0],InPipe,50);
printf("%s\n",InPipe);
exit(0);
}
}
}