fifo(命名管道)与popen建立的管道意思一样,区别在于popen的管道通常是在父子进程之间调用,而fifo可以在文件系统中看到,可以用于不同程序之间通信。fifo也支持tail -f,echo xxx > 等操作系统命令,甚至还有一个系统命令就叫mkfifo。
fifo作为一个文件,它的内容数据并不存放在文件系统中,而仅仅存在于内核里。
打开fifo文件和普通文件不同,如果尝试以读权限打开,会阻塞知道有另一个进程以写权限打开它,反之亦然。
创建fifo
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
int mkfifo(const char *pathname, mode_t mode);
其中mode和open函数的mode意思一样
select会同时监控多个文件描述符的缓冲区。它会一直阻塞,直到超时或者哪个fd的缓冲有内容了,select就认为这个fd已经准备好了,并返回。
返回值
-1 出错
1 成功
0 超时
-
#include <sys/time.h>
-
#include <sys/types.h>
-
#include <unistd.h>
-
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
参数:
nfds 需要手工设置为要监控的最大的文件描述符+1,即:max(所有被监控的fd)+1
readfds, writefds, exceptfds三个用来存放要监控的文件描述符。分别是要读的,要写的和监控出现异常的。
timeout是超时设置,传NULL表示一直阻塞,timeval里面全赋值0表示不阻塞,直接返回。
下面a.c和b.c两个程序。
b.c创建一个fifo,并用select监控标准输入,一旦有输入了,就把输入内容写到fifo里
a.c打开fifo,打印里面的内容,遇到EOF就退出。
启动后,在b程序的终端输入,输入的内容会在a的终端显示出来。
[root@server2 fifo_select]# cat b.c
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
int main(int argc, char** argv)
{
/* fifo文件名 */
char pipename[3] = "p1";
/* 创建fifo */
int ret = mkfifo(pipename, O_RDWR);
if(ret < 0)
{
/* 如果已经存在,判断是不是之前创建的fifo。fifo可以重复使用。 */
if(errno == EEXIST)
{
struct stat st;
if(stat(pipename, &st) < 0) exit(errno);
if(S_ISFIFO(st.st_mode) < 1) exit(errno);
}
else
{
exit(errno);
}
}
/* 打开fifo,此时会阻塞,知道有另一个程序以写方式打开fifo */
int p = open(pipename, O_WRONLY);
printf("pipe fd = %d\n", p);
/* select用的数据结构,用来存放要监控的文件描述符。这里监控的是标准输入 */
fd_set fs;
FD_ZERO(&fs);
FD_SET(0, &fs);
int n = 0;
char buf[1024];
while(1)
{
/* 监控fs里的文件描述符,直到有文件描述符可用为止 */
select(1, &fs, NULL, NULL, NULL);
printf("select ok\n");
/* 判断准备好的文件描述符是不是标准输入 */
if(FD_ISSET(0, &fs))
{
printf("0 ok\n");
n = read(0, buf, 1024);
if(n < 1024) buf[n] = '\0';
write(p, buf, n);
}
}
return 0;
}
a.c:
int main(int argc, char** argv)
{
FILE* p = fopen("p1", "r");
printf("open ok\n");
char c = 0;
while((c = getc(p)) != EOF)
{
printf("%c", c);
}
fclose(p);
return 0;
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26239116/viewspace-2072550/
,如需转载,请注明出处,否则将追究法律责任。