简介
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);//succss 0, fail -1
/*
mkfifo类似于open,不过其已隐含指定O_CREAT|O_EXCL,要么创建一个新的FIFO,要么返回一个EEXIST错误(指定的FIFO已存在)。
此时可以根据返回的EEXIST改用open打开这个fifo。
*/
代码
有血缘关系的进程
myhead.h
#ifndef MYHEAD_H_
#define MYHEAD_H_
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<sys/stat.h>
#define MAXLINE 4096
#endif
myfifo.c
#include"myhead.h"
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void client(int , int), server(int, int);
int main()
{
int readfd, writefd;
pid_t child;
if((mkfifo(FIFO1, FILE_MODE) < 0) && (EEXIST != errno))
{
perror("create fifo1 error");
}
if((mkfifo(FIFO2, FILE_MODE) < 0) && (EEXIST != errno))
{
unlink(FIFO1);
perror("create fifo2 error");
}
if(0 == (child = fork()))
{
readfd = open(FIFO1, O_RDONLY, 0);
writefd = open(FIFO2, O_WRONLY, 0);
server(readfd, writefd);
exit(0);
}
writefd = open(FIFO1, O_WRONLY, 0);
readfd = open(FIFO2, O_RDONLY, 0);
client(readfd, writefd);
waitpid(child, NULL, 0);
close(readfd);
close(writefd);
unlink(FIFO1);
unlink(FIFO2);
exit(0);
}
void client(int readfd, int writefd)
{
ssize_t len;
char buff[MAXLINE] = {0};
int flag = 0;
fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if('\n' == buff[len - 1])
len--;
flag = fcntl(readfd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(readfd, flag, 0);
write(writefd, buff, len);
sleep(1);
while((len = read(readfd, buff, MAXLINE)) > 0)
{
puts(buff);
}
printf("clinet over\n");
close(readfd);
close(writefd);
return;
}
void server(int readfd, int writefd)
{
ssize_t len;
char buff[MAXLINE] = {0};
int fd;
read(readfd, buff, MAXLINE);
fd = open(buff, O_RDONLY);
while((len = read(fd, buff, MAXLINE)) > 0)
{
write(writefd, buff, len);
}
printf("close server\n");
return;
}
无血缘版本
fifoSer.c
#include"myhead.h"
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void server(int, int);
int main()
{
int readfd, writefd;
pid_t child;
if((mkfifo(FIFO1, FILE_MODE) < 0) && (EEXIST != errno))
{
perror("create fifo1 error");
}
if((mkfifo(FIFO2, FILE_MODE) < 0) && (EEXIST != errno))
{
unlink(FIFO1);
perror("create fifo2 error");
}
readfd = open(FIFO1, O_RDONLY, 0);
writefd = open(FIFO2, O_WRONLY, 0);
server(readfd, writefd);
close(readfd);
close(writefd);
unlink(FIFO1);
unlink(FIFO2);
exit(0);
}
void server(int readfd, int writefd)
{
ssize_t len;
char buff[MAXLINE] = {0};
int fd;
read(readfd, buff, MAXLINE);
fd = open(buff, O_RDONLY);
while((len = read(fd, buff, MAXLINE)) > 0)
{
write(writefd, buff, len);
}
printf("close server\n");
return;
}
fifoCli.c
#include"myhead.h"
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
void client(int , int);
int main()
{
int readfd, writefd;
pid_t child;
if((mkfifo(FIFO1, FILE_MODE) < 0) && (EEXIST != errno))
{
perror("create fifo1 error");
}
if((mkfifo(FIFO2, FILE_MODE) < 0) && (EEXIST != errno))
{
unlink(FIFO1);
perror("create fifo2 error");
}
writefd = open(FIFO1, O_WRONLY, 0);
readfd = open(FIFO2, O_RDONLY, 0);
//readfd = open(FIFO2, O_RDONLY|O_NONBLOCK, 0);
client(readfd, writefd);
waitpid(child, NULL, 0);
close(readfd);
close(writefd);
unlink(FIFO1);
unlink(FIFO2);
exit(0);
}
void client(int readfd, int writefd)
{
ssize_t len;
char buff[MAXLINE] = {0};
int flag = 0;
fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if('\n' == buff[len - 1])
len--;
flag = fcntl(readfd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(readfd, flag, 0);
write(writefd, buff, len);
sleep(1);
while((len = read(readfd, buff, MAXLINE)) > 0)
{
puts(buff);
}
printf("clinet over\n");
return;
}
注意: fifo读写的打开顺序,如果当前没有任何进程打开某个FIFO来写,那么打开该FIFO来读的进程将阻塞,容易形成死锁。