- 论坛徽章:
- 0
|
命名管道一般简称为FIFO。FIFO在UNIX/Linux中用的比较多。FIFO的具体内容就不说了。
值得一提的是,在两个进程分别用只读和只写的方式打开FIFO的情况下,
如果只写打开FIFO的进程先退出,或者先关闭FIFO;
则只读打开FIFO的进程的read函数将读到0字节;这个时候只读进程也应该关闭FIFO。
如果不关闭FIFO,则select将一直报告有读描述符准备好,造成极大CPU资源浪费。
eg。有两个进程,进程receiver用来接收某个fifo的数据,进程sender用来向某个fifo发送数据。
#define BUFSIZE 128
#define FIFO "fifo"
program receiver:
#include ...
int main(int argc, char *argv)
{
int fd;
char buff[BUFSIZE];
fd_set readfds;
struct timeval tv;
int value;
fd = open(FIFO, O_RDONLY | O_NONBLOCK)
if (fd
value = fcntl(fd, F_GETFL);
if (value
while (1)
{
tv.tv_sec = 3;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
value = select(fd+1, &readfds, NULL, NULL, &tv);
if (value > 0)
{
printf("%d fds are ready.\n", i);
if (FD_ISSET(fd, &readfds))
{
printf("FIFO is ready for read.\n");
memset(buff, 0, BUFSIZE);
read(fd, buff, BUFSIZE-1);
printf("received stirng: %s\n", buff);
}
}
else if (value == 0)
{
printf("timeout, No file descriptor ready.\n");
}
else
{
printf("have error occured, exit program!!!\n");
close(fd);
return -1;
}
}
close(fd);
return 0;
}
program sender:
#include ...
int main(int argc, char *argv[])
{
int fd;
char buff[BUFSIZE];
int len;
fd = open(FIFO, O_WRONLY);
if (fd
memset(buff, 0, BUFSIZE);
strncpy(buff, "123456789", BUFSIZE-1);
if (write(fd, buff, strlen(buff)) != strlen(buff))
{
perror(write);
close(fd);
return -1;
}
else
{
printf("write success!\n");
}
close(fd);
return 0;
}
编译这两个程序,不管先启动哪个程序,sender都能得到正确的结果.但receiver却不能正确的运行.
结果如下:
sender:
open fifo success!
write success!
receiver:
open fifo success!
1 fds are ready.
FIFO is ready for read.
received string:123456789
1 fds are ready.
FIFO is ready for read.
received stirng:
1 fds are ready.
FIFO is ready for read.
received stirng:
......
在屏幕上不停的循环显示 "1 fds are ready. FIFO is ready for read. received stirng:"
为什么会出现这种情况呢? 是因为当FIFO的write端关闭后,会通知read端;这样在read端就会变得可以读,但并没有任何数据;
这样的目的就是通知读端关闭.所以我们只要简单的关闭FIFO描述符就可以了.
但是,receiver程序的目的是打开某个FIFO,并一直等待其它程序的数据,如果我们关闭了的话程序也就推出了.
所以我们要做的是应该是重新打开.
receiver程序新版如下:
program receiver:
#include ...
int open_fifo(void)
{
int fd;
int value;
fd = open(FIFO, O_RDONLY | O_NONBLOCK)
if (fd
value = fcntl(fd, F_GETFL);
if (value
int main(int argc, char *argv)
{
int fd;
char buff[BUFSIZE];
fd_set readfds;
struct timeval tv;
if((fd = open_fifo()) == -1)
{
return -1;
}
while (1)
{
tv.tv_sec = 3;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
value = select(fd+1, &readfds, NULL, NULL, &tv);
if (value > 0)
{
printf("%d fds are ready.\n", i);
if (FD_ISSET(fd, &readfds))
{
printf("FIFO is ready for read.\n");
memset(buff, 0, BUFSIZE);
if (read(fd, buff, BUFSIZE-1)
close(fd);
return 0;
}
程序修改成这样,就不存在上面的问题了.
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/7835/showart_107128.html |
|