无名管道 Pipe
同主机进程间数据交互机制:
- 无名管道(PIPE):只有创建该管道的程序,才能够找到该管道(亲缘进程通信)
- 单向传输
- 控制进程只有pipe的一端
- pipe的阻塞操作
*fd[0] 读 fd[1]写
SIGPIPE - 无名管道的内核资源在通信两进程退出后会自动释放,不能像普通文件一样存储信息,不能使用lseek来修改当前pipe的使用位置
read write 返回-1
会收到sigpipe信号
Demo
#include<stdio.h>
#include<errno.h>
#include<sys/wait.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
int main()
{
int pipe_fd[2] = {-1,-1};
if(pipe(pipe_fd) < 0){
printf("pipe error, %s\n",strerror(errno));
return 1;
}
pid_t id = fork();
if(id == 0){
//child write
close(pipe_fd[0]);
char *msg = "child write:enenshiwo\n";
while(1){
write(pipe_fd[1],msg,strlen(msg));
sleep(1);
}
}else{
//father read
close(pipe_fd[1]);
char buf[1024];
while(1){
buf[0] = '\0';
char *msg_f = "father write:enenshiwo\n";
ssize_t _sz = read(pipe_fd[0],buf,sizeof(buf) - 1);
if(_sz > 0){
buf[_sz] = '\0';
}
printf("father read : %s\n",buf);
}
wait(NULL);
}
return 0;
}
有名管道 fifo
- FIFO 是依赖于文件系统,
依赖于文件系统,像普通文件一样具有磁盘路径,文件权限和其他属性,所有程序都可以通过path找到有名管道
- fifo是一个文件,存储信息在内存,当两个进程都消失,数据消息,文件只有接口的作用
- mkfifo
int mkfifo(const char* pathname, mode_t mode); - 单项通信
- 只能够进行少量数据传输
- 只能一对一进行传输
- 两个进程,中途退出了一个进程,未退出的一端如果是写操作的话,返回sigpipe信号
- 未退出的一端如果是阻塞读操作的话,该读操作不会继续阻塞,直接返回0
Demo
fifo_write.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "/tmp/my_fifo"
int main(int argc,char *argv[])
{
int pipe_fd;
int res;
char buffer[]="hello world!";
if (access(FIFO_NAME, F_OK) == -1)
{
res = mkfifo(FIFO_NAME, 0766);
if (res != 0)
{
fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIFO O_WRONLY\n", getpid());
pipe_fd = open(FIFO_NAME, O_WRONLY);
printf("the file's descriptor is %d\n", pipe_fd);
if (pipe_fd != -1)
{
res = write(pipe_fd, buffer, sizeof(buffer));
if (res == -1)
{
fprintf(stderr, "Write error on pipe\n");
exit(EXIT_FAILURE);
}
printf("write data is %s,%d bytes is wirte\n",buffer,res);
(void)close(pipe_fd);
}
else
exit(EXIT_FAILURE);
printf("Process %d finished\n", getpid());
exit(EXIT_SUCCESS);
}
fifo_read.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "/tmp/my_fifo"
int main(int argc,char *argv[])
{
int pipe_fd;
int res;
char buffer[4096];
int bytes_read = 0;
memset(buffer, '\0', sizeof(buffer));
printf("Process %d opening FIFO O_RDONLY\n", getpid());
pipe_fd = open(FIFO_NAME, O_RDONLY);
printf("the file's descriptor is %d\n",pipe_fd);
if (pipe_fd != -1)
{
bytes_read = read(pipe_fd, buffer, sizeof(buffer));
printf("the read data is %s\n",buffer);
close(pipe_fd);
}
else
exit(EXIT_FAILURE);
printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);
exit(EXIT_SUCCESS);
}