管道(无名管道)
(1)管道通信的原理:内核维护的一块内存,有读端和写端(管道是单向通信的)
(2)管道通信的方法:父进程创建管理后fork子进程,子进程继承父进程的管道fd
(3)管道通信的限制:只能在父子进程间通信、半双工
(4)管道通信的函数:pipe、write、read、close
有名管道(fifo)
(1)有名管道的原理:实质也是内核维护的一块内存,表现形式为一个有名字的文件
(2)有名管道的使用方法:固定一个文件名,2个进程分别使用mkfifo创建fifo文件,然后分别open打开获取到fd,然后一个读一个写
(3)管道通信限制:半双工(注意不限父子进程,任意2个进程都可)
(4)管道通信的函数:mkfifo、open、write、read、close
一、无名管道
pipe的函数原型:
int pipe(int pipefd[2]);
功能:经由参数pipefd返回两个文件描述符 ( pipefd[2] 有两个文件描述符组成: pipefd[0]和pipefd[1] )
pipefd[0] 用于从管道读数据, pipefd[1] 用于往管道写数据
返回值:管道创建成功返回0,失败返回-1;
示例代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(void)
{
int fd_pipe[2];
pid_t pid;
char sendBuf[256] = "hello pipe";
char revBuf[256] = {0};
if(pipe(fd_pipe) < 0)
{
perror("pipe error");
return -1;
}
pid = fork();
if(pid < 0)
{
perror("fork error");
return -1;
}
if(pid == 0) // 子进程负责发送数据
{
write(fd_pipe[1],sendBuf,sizeof(sendBuf));
exit(0);
}
else //父进程负责接收数据
{
wait(NULL);
read(fd_pipe[0],revBuf,sizeof(revBuf));
printf("revBuf = %s.\n",revBuf);
exit(0);
}
return 0;
}
二、有名管道
示例代码如下:
(进程1)创建有名管道,然后开打,接着是一直循环读取管道中的内容
(进程2)往该有名管道中写入数据
1. (进程1)fifo_r.c
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define P_FIFO "/tmp/p_fifo"
int main(int argc, char** argv)
{
char cache[100];
int fd;
memset(cache,0, sizeof(cache));
if(mkfifo(P_FIFO,O_CREAT | O_RDWR) < 0)
{
printf("create named pipe failed.\n");
}
fd= open(P_FIFO,O_RDONLY|O_NONBLOCK); // 非阻塞方式打开,只读
while(1)
{
memset(cache,0, sizeof(cache));
if((read(fd,cache, 100)) == 0 )
{
printf("nodata:\n");
}
else
printf("getdata:%s\n", cache);
sleep(1); //休眠1s
}
close(fd);
return 0;
}
2. (进程2)fifo_w.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define P_FIFO "/tmp/p_fifo"
int main(int argc, char argv[])
{
char fifo_buf[100];
int fd;
fd= open(P_FIFO,O_WRONLY|O_NONBLOCK); //非阻塞方式
while(1)
{
printf("please input the write data.\n");
memset(fifo_buf,0,sizeof(fifo_buf));
scanf("%s",fifo_buf);
write(fd,fifo_buf, sizeof(fifo_buf));
}
close(fd);
return 0;
}