免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 627 | 回复: 0
打印 上一主题 下一主题

fifo 一例 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-30 11:42 |只看该作者 |倒序浏览
  命名管道一般简称为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
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP