-->

为什么当一个文件被写入(使用轮询ÇLinux的功能),不仅显示此消息?(Why is this me

2019-07-31 14:33发布

我是在C编程阅读有关调查和建立在给定的应用调查(2)手册页 。

这里是例子:

#include<stdio.h>
#include <stropts.h>
#include <poll.h>
#include <fcntl.h>

int main() {

    struct pollfd fds[2];
    int timeout_msecs = -1;
    int ret;
    int i;

    /* Open STREAMS device. */
    fds[0].fd = open("/home/jeshwanth/mywork/poll/dev0", O_RDONLY);
    fds[1].fd = open("/home/jeshwanth/mywork/poll/dev1", O_RDONLY);
    fds[0].events = POLLOUT | POLLWRBAND;
    fds[1].events = POLLOUT | POLLWRBAND;

    while (1) {
        ret = poll(fds, 2, timeout_msecs);

        if (ret > 0) {
            /* An event on one of the fds has occurred. */
            for (i = 0; i < 2; i++) {
                if (fds[i].revents != 0) {
                    /* Priority data may be written on device number i. */
                    printf(
                            "Priority Data may be written on device number %d POLLWRBAND\n",
                            i);

                }
                if (fds[i].revents = !0) {
                    /* Data may be written on device number i. */
                    printf("Data may be written on device number %d POLLOUT\n",
                            i);
                }
                if (fds[i].revents = !0) {
                    /* A hangup has occurred on device number i. */
                    printf("A hangup has occurred on device number %d\n", i);

                }
            }
        }
    }
    return 0;
}

注:装置0和DEV1是正常的文件。 当我运行该程序,如果没有事件发生在装置0和DEV1,显示该消息。 但我期待当一些写入到文件中,也只那么它应该显示的消息。 我错了吗?

Answer 1:

轮询它输出的准备并不意味着你会得到通知时,一些输出时:这意味着,当有可用的输出缓冲空间,所以你可以你就会收到通知的输出(但你还是应该检查你的输出功能的返回值该缓冲器状态可能已经轮询和输出之间变化;总是检查返回值)。



Answer 2:

最小的FIFO命名管道实例

您将无法看到什么有趣的与普通的文件,因为这些总是给POLLIN立刻: 如何选择()定期文件描述符(非插座)等吗?

一起玩最简单的方法poll是使用命名管道,如下图所示。 这应该为你准备他们的主要应用:插座和设备文件。

下面来源。 用法:

sudo mknod poll0.tmp p
sudo mknod poll1.tmp p
sudo chmod 666 poll*.tmp
./poll.out

在另一个shell:

printf a > poll0.tmp
printf b > poll1.tmp

输出:

loop
POLLIN i=0 n=1 buf=a
loop
POLLHUP i=0
loop
POLLIN i=1 n=1 buf=b
POLLHUP i=1
loop

因此,注意如何poll等待不循环的读取。

散热器例如:

(while true; do date; sleep 1; done) > poll0.tmp &
(while true; do date; sleep 2; done) > poll1.tmp &

0被写入每一秒,并且1每两秒,其示出了如何poll()是处理两个输入同时地,而不会停止对方。

资源:

#define _XOPEN_SOURCE 700
#include <fcntl.h> /* creat, O_CREAT */
#include <poll.h> /* poll */
#include <stdio.h> /* printf, puts, snprintf */
#include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */
#include <unistd.h> /* read */

int main(void) {
    enum { N = 2 };
    char buf[1024], path[1024];
    int fd, i, n;
    short revents;
    struct pollfd pfds[N];

    for (i = 0; i < N; ++i) {
        snprintf(path, sizeof(path), "poll%d.tmp", i);
        /* O_NONBLOCK is required or else the open blocks
         * until the other side of the pipe opens. */
        fd = open(path, O_RDONLY | O_NONBLOCK);
        if (fd == -1) {
            perror("open");
            exit(EXIT_FAILURE);
        }
        pfds[i].fd = fd;
        /* Only events in this mask will be listened to.
         * However, there are also some events that are unmaskable,
         * notably POLLHUP when pipe closes! */
        pfds[i].events = POLLIN;
    }
    while (1) {
        puts("loop");
        i = poll(pfds, N, -1);
        if (i == -1) {
            perror("poll");
            exit(EXIT_FAILURE);
        }
        for (i = 0; i < N; ++i) {
            revents = pfds[i].revents;
            if (revents & POLLIN) {
                n = read(pfds[i].fd, buf, sizeof(buf));
                printf("POLLIN i=%d n=%d buf=%.*s\n", i, n, n, buf);
            }
            if (revents & POLLHUP) {
                printf("POLLHUP i=%d\n", i);

                /* This happens when the other side closed.
                 * This event is only cleared when we close the reader. */

                /* poll won't set POLLHUP anymore once all fds are closed.
                 * Any futher polls on this will give the POLLNVAL event instead. */
                close(pfds[i].fd);

                /* negative fds are ignored. So if we negate an FD,
                 * we can both turn if off for a while, and turn it on
                 * later on by re-nagating it. */
                pfds[i].fd *= -1;
            }
        }
    }
}

编译:

gcc -o poll.out -std=c99 poll.c

经测试在Ubuntu 14.04。

GitHub的上游 。

该行:

close(pfds[i].fd);
pfds[i].fd *= -1;

需要要不然你POLLHUP永远,请参阅: 如何使用投票C函数在Linux中观看命名管道?

更好玩,创建一个Linux内核模块实现什么样的poll FOPS: 如何查询功能添加到内核模块的代码?



Answer 3:

我给你如何纠正它的提示。 revents被解释为几个位标志。

/* check for priority write readiness */
if (fds[i].revents & POLLWRBAND) {
  printf("Priority Data may be written on device number %d POLLWRBAND\n", i);
}

/* check for write readiness */
if (fds[i].revents & POLLOUT) {
  printf("Data may be written on device number %d POLLOUT\n", i);
}

/* check for hang-up */
if (fds[i].revents & POLLHUP) {
  printf("A hangup has occurred on device number %d\n", i);
}


文章来源: Why is this message not only displayed when a file is written to (using the poll C Linux function)?
标签: c linux polling