携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天
管道
system()\exec()\fork()
进程通信:信号量、共享内存、消息队列、管道
管道:实质缓冲区,进行进程之间的通信 管道数据用过之后就消失
管道文件 p 伪文件
命名管道:fifo(有名字,类似于文件)
匿名管道:pipe(没有名字) ls /home | grep t
进程1(写操作) --> 临时缓冲区(管道)-->进程2( 读操作)
一、pipe()函数:建立一个管道
#include <unistd.h>
int pipe(int filedes[2]);
使用pipe前,需要定义一个一维数组,包括两个成员,未来
作为文件描述符,一个控制读端、另一个控制写端。
常常配合fork,来作为两个亲缘关系进程的通信。
(一)读管道:
1.管道有数据。read返回实际读到的字节数。
2.管道无数据:1)无写端,read返回0
2)有写端,read阻塞等待。
(二)写管道:
1无读端,异常终止(sigpie 导致)
2.有读端
1)管道已满,阻塞等待
2)管道未满,返回写出的字节个数。
sleep(10)
(三)管道阻塞和管道操作的原子性
当管道的写端没有关闭时,如果写请求的字节数目大于阈值PIPE_BUF,写操作的返回值是管道中目前的数据字节数;如果写请求的字节数目不大于阈值PIPE_BUF,则返回管道中现有数据字节数。
128k 200k 写两次 等待读进程读后,继续写。
如果管道数据已满,写进程阻塞,等待sleep读进程取走数据;
写缓冲 128k,读缓冲10k 应读13次
命名管道(FIFO)
pipe.c:文件 write、read函数
进程 fork函数
进程通信pipe函数 命名管道:fifo文件
shell命令:mkfifo 文件名
程序建立 mkfifo( )函数
#include <sys/types.h>
#include <sys/stat.h>
Int mkfifo(const *path_name, mode_t mode)
建立成功后,应用管道,把它作为文件进行操作。
建立两个进程,对所建管道分别进行读、写操作。
写入管道的内容,执行时看不到;把管道内容输出到屏幕即可见。
读进程代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
int fd,len;
char buf[1024];
if(argc<2)
{printf("enter like ./out fifoname\n");
return -1;
}
fd=open(argv[1],O_RDONLY);
while(1)
{
len=read(fd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,len);
sleep(2);
}
close(fd);
return 0;
}
写进程代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
int i,fd,len;
char buf[1024];
if(argc<2)
{printf("enter like ./out fifoname\n");
}
fd=open(argv[1],O_WRONLY);
if(fd<0)printf("open failure");
i=0;
while(1)
{
sprintf(buf,"hello myfifo %d\n",i++);
write(fd,buf,strlen(buf));
sleep(2);
}
close(fd);
return 0;
}