fifo 一例
时间:2006-04-30 来源:iry
命名管道一般简称为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 < 0)
{
perror("open fifo");
return -1;
}
else
{
printf("open fifo success\n");
} value = fcntl(fd, F_GETFL);
if (value < 0)
{
close(fd);
return -1;
}
value &= (~O_NONBLOCK);
if (fcntl(fd, F_SETFL, value) < 0)
{
close(fd);
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);
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 < 0)
{
perror("open fifo");
reutrn -1;
}
else
{
printf("open fifo success!\n");
} 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 < 0)
{
perror("open fifo");
return -1;
}
else
{
printf("open fifo success\n");
} value = fcntl(fd, F_GETFL);
if (value < 0)
{
close(fd);
return -1;
}
value &= (~O_NONBLOCK);
if (fcntl(fd, F_SETFL, value) < 0)
{
close(fd);
return -1;
}
return fd;
} 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) <= 0)
{
printf("error or notify close fifo. reopen it.\n");
close(fd);
if((fd = open_fifo()) == -1)
{
return -1;
}
}
else
{
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;
} 程序修改成这样,就不存在上面的问题了.
值得一提的是,在两个进程分别用只读和只写的方式打开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 < 0)
{
perror("open fifo");
return -1;
}
else
{
printf("open fifo success\n");
} value = fcntl(fd, F_GETFL);
if (value < 0)
{
close(fd);
return -1;
}
value &= (~O_NONBLOCK);
if (fcntl(fd, F_SETFL, value) < 0)
{
close(fd);
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);
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 < 0)
{
perror("open fifo");
reutrn -1;
}
else
{
printf("open fifo success!\n");
} 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 < 0)
{
perror("open fifo");
return -1;
}
else
{
printf("open fifo success\n");
} value = fcntl(fd, F_GETFL);
if (value < 0)
{
close(fd);
return -1;
}
value &= (~O_NONBLOCK);
if (fcntl(fd, F_SETFL, value) < 0)
{
close(fd);
return -1;
}
return fd;
} 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) <= 0)
{
printf("error or notify close fifo. reopen it.\n");
close(fd);
if((fd = open_fifo()) == -1)
{
return -1;
}
}
else
{
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;
} 程序修改成这样,就不存在上面的问题了.
相关阅读 更多 +