FIFO,命名管道。可以在不相关的进程间进行通信。FIFO是一种文件类型,下面为创建FIFO文件的函数
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
成功则返回0,否则返回-1.
打开关闭FIFO如同普通文件方法一样。应注意打开一个FIFO时,可选择非阻塞标志(O_NONBLOCK),默认为阻塞
1.阻塞情况下:只读打开会阻塞到有进程为写打开FIFO。为写打开FIFO会阻塞到有进程为读打开FIFO。
2.非阻塞情况下:只读打开会立即返回。只写打开时,如果没有进程为读打开次FIFO,则只写打开会报错返回,errno为ENXIO
产生SIGPIPE:写一个尚无进程为读打开的FIFO。
结束:FIFO最后一个写进程关闭FIFO,则该FIFO的读进程产生一个文件结束标志。要想避免产生文件结束标志,则可将以读-写方式打开FIFO。
为了免产生文件结束标志,将服务器进程中的FIFO以读-写方式打开。。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
成功则返回0,否则返回-1.
打开关闭FIFO如同普通文件方法一样。应注意打开一个FIFO时,可选择非阻塞标志(O_NONBLOCK),默认为阻塞
1.阻塞情况下:只读打开会阻塞到有进程为写打开FIFO。为写打开FIFO会阻塞到有进程为读打开FIFO。
2.非阻塞情况下:只读打开会立即返回。只写打开时,如果没有进程为读打开次FIFO,则只写打开会报错返回,errno为ENXIO
产生SIGPIPE:写一个尚无进程为读打开的FIFO。
结束:FIFO最后一个写进程关闭FIFO,则该FIFO的读进程产生一个文件结束标志。要想避免产生文件结束标志,则可将以读-写方式打开FIFO。
FIFO可以有多个写进程,为了避免各个进程所写的数据穿插,则应将一次写入FIFO的数据限制最大数据量为PIPE_BUF
服务器进程(读进程)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
int main(int argc, char **argv)
{
int rfp, n;
char line[PIPE_BUF];
if(argc != 2){
fprintf(stderr, "usage:a.out <fifo_pathname>\n");
exit(1);
}
if(access(argv[1], F_OK) == 0){
fprintf(stderr, "the file has exists,errno:%s\n", strerror(errno));
exit(1);
}
if(mkfifo(argv[1], S_IRUSR|S_IWUSR|S_IROTH|S_IWOTH|S_IRGRP|S_IWGRP) < 0){
fprintf(stderr, "mkfifo error,errno:%s\n", strerror(errno));
exit(1);
}
if((rfp = open(argv[1], O_RDONLY | O_WRONLY)) < 0){
fprintf(stderr, "open error,errno:%d,%s\n", errno, strerror(errno));
exit(1);
}
fprintf(stdout, "begin read the fifo\n");
while(1){
n = read(rfp, line, PIPE_BUF);
if(n < 0){
//if(errno == EAGAIN)
// continue;
fprintf(stderr, "read error,errno:%d,%s\n", errno, strerror(errno));
break;
}else if(n == 0){
//fprintf(stdout, " read the end\n");
//continue;
break;
}else{
line[n] = 0;
fprintf(stdout,"FIFO MSG:%s\n", line);
}
}
close(rfp);
if(unlink(argv[1]) < 0){
fprintf(stderr, "unlink error,errno:%s\n", strerror(errno));
exit(1);
}
return 0;
}
客户端进程(写进程)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
int main(int argc, char **argv)
{
int wfp, i;
char line[PIPE_BUF];
if(argc != 2){
fprintf(stderr, "usage:a.out <fifo_pathname>\n");
exit(1);
}
if(access(argv[1], F_OK) < 0){
fprintf(stderr, "the file hasn't exists,errno:%s\n", strerror(errno));
exit(1);
}
if((wfp = open(argv[1], O_WRONLY)) < 0){
fprintf(stderr, "open error,errno:%d,%s\n", errno, strerror(errno));
exit(1);
}
fprintf(stdout, "begin write the fifo\n");
for(i = 0; i < 20; i++){
sprintf(line, "This is test ,num(%d)\n", i);
if(write(wfp, line, strlen(line)) < 0){
fprintf(stderr, "write error,errno:%s\n", strerror(errno));
close(wfp);
exit(1);
}
}
close(wfp);
return 0;
}
为了免产生文件结束标志,将服务器进程中的FIFO以读-写方式打开。。