POLL轮询事件类型使用方法

        在Linux系统中,使用poll函数来进行轮询。IO多路复用Epoll、Poll、Select介绍可参考前面的文章:C++中的IO多路复用(select、poll、epoll)总结_c++ epoll select poll是什么-CSDN博客   poll函数原型如下:

#include <poll.h>


    int poll(struct pollfd *fds, nfds_t nfds, int timeout);

        poll函数接受一个struct pollfd数组,该数组包含多个文件描述符和相应的事件类型。poll函数会阻塞,直到有一个或多个文件描述符上的事件发生。一旦发生事件,poll函数会返回,同时将对应的文件描述符和事件类型存储在struct pollfd结构体的revents字段中。

/* Data structure describing a polling request.  */
struct pollfd
  {
    int fd;			/* File descriptor to poll.  */
    short int events;		/* Types of events poller cares about.  */
    short int revents;		/* Types of events that actually occurred.  */
  };

        

POLL定义了一系列的事件类型,例如:

  • POLLIN:表示有数据可读。
  • POLLPRI:表示有紧急数据可读。
  • POLLOUT:表示可以写入。
  • POLLERR:表示发生错误。
  • POLLHUP:表示关闭连接。
  • POLLNVAL:表示无效的轮询请求。

可以使用poll函数进行轮询,在事件发生之后,通过检查revents字段来确定具体的事件类型,并在相应的条件下进行处理。示例代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/poll.h>

int main() {
    int fd1, fd2;
    struct pollfd fds[2];

    // 打开文件描述符,此处仅示意
    fd1 = open("file1.txt", O_RDONLY);
    fd2 = open("file2.txt", O_WRONLY);

    // 初始化pollfd结构体数组
    fds[0].fd = fd1;
    fds[0].events = POLLIN;   // 监听可读事件

    fds[1].fd = fd2;
    fds[1].events = POLLOUT;  // 监听可写事件

    // 轮询事件
    int numEvents = poll(fds, 2, 5000);  // 监听2个文件描述符,超时时间为5秒

    if (numEvents > 0) {
        // 遍历检查每个文件描述符上的事件
        for (int i = 0; i < 2; i++) {
            if (fds[i].revents & POLLIN) {
                printf("数据可读\n");
                // 在此处理可读事件
                // 例如从文件中读取数据
            }
            
            if (fds[i].revents & POLLOUT) {
                printf("可写数据\n");
                // 在此处理可写事件
                // 例如向文件中写入数据
            }
        }
    } else if (numEvents == -1) {
        perror("poll");
        exit(EXIT_FAILURE);
    } else {
        printf("超时\n");
        // 在此处理超时事件
    }

    // 关闭文件描述符,此处仅示意
    close(fd1);
    close(fd2);
    
    return 0;
}

        那么,我们为什么可以使用位运算符来存储标志位呢?首先我们可以查看POLLIN等事件在源代码中的值:

#ifndef _SYS_POLL_H
# error "Never use <bits/poll.h> directly; include <sys/poll.h> instead."
#endif

/* Event types that can be polled for.  These bits may be set in `events'
   to indicate the interesting event types; they will appear in `revents'
   to indicate the status of the file descriptor.  */
#define POLLIN		0x001		/* There is data to read.  */
#define POLLPRI		0x002		/* There is urgent data to read.  */
#define POLLOUT		0x004		/* Writing now will not block.  */

#if defined __USE_XOPEN || defined __USE_XOPEN2K8
/* These values are defined in XPG4.2.  */
# define POLLRDNORM	0x040		/* Normal data may be read.  */
# define POLLRDBAND	0x080		/* Priority data may be read.  */
# define POLLWRNORM	0x100		/* Writing now will not block.  */
# define POLLWRBAND	0x200		/* Priority data may be written.  */
#endif

#ifdef __USE_GNU
/* These are extensions for Linux.  */
# define POLLMSG	0x400
# define POLLREMOVE	0x1000
# define POLLRDHUP	0x2000
#endif

/* Event types always implicitly polled for.  These bits need not be set in
   `events', but they will appear in `revents' to indicate the status of
   the file descriptor.  */
#define POLLERR		0x008		/* Error condition.  */
#define POLLHUP		0x010		/* Hung up.  */
#define POLLNVAL	0x020		/* Invalid polling request.  */

通过上面的代码我们可以看到,这些事件都被赋予了一定的值,我们将其转化为二进制再看看,可以发现每一个事件对应着二进制的每一位,即我们可以通过位运算来控制数据的每一位对应的事件:

 具体位运算方法可以参考本文:利用位运算符设置标志位-CSDN博客

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值