有名管道用于无血缘关系间的进程通信,需要注意的有:
如果想双方都能随时发送和接收信息,各自互不干扰,那么就必须都包含发送和接收的代码。这是和无名管道的区别,无名管道是一个进程启动后,fork一个子进程出来,父子进程都有发送和接收端的代码。而有名管道用于无血缘关系的进程通信,那么一个进程如果想包含发送和接收的代码,就必须也fork一个子进程出来,父子进程一个负责发送,一个负责接收,而不是像无名管道那样,父子进程都有接收发送代码。
demo:
a.out
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#define PATHNAME1 "./fifo1"
#define PATHNAME2 "./fifo2"
void print_err(char* str)
{
perror(str);
exit(-1);
}
char buf[1024] = {0};
int main()
{
int fd[2] = { 0 };
pid_t pid = fork();
if(pid>0)
{
fd[0] = open(PATHNAME1,O_RDWR);
if(fd[0] == -1) print_err("open fail:");
while(1)
{
read(fd[0],buf,sizeof(buf));
printf("rcv:%s\n",buf);
bzero(buf,sizeof(buf));
}
}
else if(pid == 0)
{
fd[1] = open(PATHNAME2,O_RDWR);
if(fd[1] == -1) print_err("open fail:");
while(1)
{
read(0,buf,sizeof(buf));
write(fd[1],buf,sizeof(buf));
bzero(buf,sizeof(buf));
}
}
return 0;
}
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define PATHNAME1 "./fifo1"
#define PATHNAME2 "./fifo2"
void print_err(char* str)
{
perror(str);
exit(-1);
}
char buf[1024] = { 0 };
int main()
{
int fd[2] = { 0 };
int ret[2] = { 0 };
ret[0] = mkfifo(PATHNAME1,0664);
if(ret[0] == -1 && errno!=EEXIST) print_err("mkfifo fail:");
ret[1] = mkfifo(PATHNAME2,0664);
if(ret[1] == -1 && errno!=EEXIST) print_err("mkfifo fail:");
pid_t pid = fork();
if(pid>0)
{
fd[0] = open(PATHNAME1,O_RDWR);
if(fd[0] == -1) print_err("open fail:");
while(1)
{
read(0,buf,sizeof(buf));
write(fd[0],buf,sizeof(buf));
bzero(buf,sizeof(buf));
}
}
if(pid == 0)
{
fd[1] = open(PATHNAME2,O_RDWR);
if(fd[1] == -1) print_err("open fail:");
while(1)
{
read(fd[1],buf,sizeof(buf));
printf("rcv data:%s\n",buf);
bzero(buf,sizeof(buf));
}
}
return 0;
}