Linux 命令 poll 和 ppoll 详解 + 实例

Posted Linux猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 命令 poll 和 ppoll 详解 + 实例相关的知识,希望对你有一定的参考价值。


 🎈 作者:Linux猿

🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

🎈 关注专栏: 数据结构和算法成神路【精讲】优质好文持续更新中……🚀🚀🚀

🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬


本文主要对 Linux 命令 poll 和 ppoll 命令进行详细讲解,最后会以实例的方式进行说明,下面一起来看下吧!

一、基本概念

poll 和 ppoll 可以同时监听多个文件描述符上的事件,poll 函数和 ppoll 函数之间的关系类似于 select 和 pselect。

二、poll 和 ppoll 函数

2.1 poll 函数

头文件:

#include <poll.h>

声明:

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

其中,各参数为:

(1)struct pollfd *fds

  该参数是待监控事件的集合,struct pollfd 结构如下所示:

struct pollfd 
    int   fd;     //文件描述符
    short events; //需求的事件类型
    short revents;//返回的事件类型
;

字段 fd 包含打开文件的文件描述符。如果为负数,则忽略相应的时间字段,并返回 0,。如果此字段指定为零,则 fd 的所有事件都将被忽略,并且 revents 返回 0。

其中,events 和 revents 事件类型有如下种类:

#define POLLIN            0x0001 //有数据需要读取
#define POLLPRI          0x0002 //
#define POLLOUT        0x0004 //可以写入数据
#define POLLERR        0x0008 //调用出错,仅在revents中出现
#define POLLHUP        0x0010 //调用中断,仅在revents中出现
#define POLLNVAL       0x0020 //无效的请求,仅在revents中出现

(2)nfds_t nfds

  监听事件的个数,表示 fds 数组的长度。

(3)int timeout

阻塞时间,单位是毫秒,函数调用一直等待,直到发生下列三种情况之一:

  • 有事件发生;
  • 等待超时;
  • 调用被中断;

2.2 ppoll 函数

poll 函数和 ppoll 函数之间的关系类似于 select 和 pselect。

头文件:

#define _GNU_SOURCE
#include <signal.h>
#include <poll.h>

函数声明:

 int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask);

函数执行成功返回正数,表示发生事件的描述符的数量;如果返回值为 0,表示调用超时,且没有文件描述符就绪;如果返回 -1,表示出错。 

三、实例

下面来看下实例,如下所示:

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

#define errExit(msg)   do   perror(msg); exit(EXIT_FAILURE);  while (0)

int main(int argc, char *argv[])

    int nfds, num_open_fds;
    struct pollfd *pfds;

    if (argc < 2)
    
        fprintf(stderr, "Usage: %s file...\\n", argv[0]);
        exit(EXIT_FAILURE);
    

    num_open_fds = nfds = argc - 1;
    pfds = calloc(nfds, sizeof(struct pollfd));
    if (pfds == NULL)
        errExit("malloc");

    /* Open each file on command line, and add it 'pfds' array. */

    for (int j = 0; j < nfds; j++)
    
        pfds[j].fd = open(argv[j + 1], O_RDONLY);
        if (pfds[j].fd == -1)
            errExit("open");

        printf("Opened \\"%s\\" on fd %d\\n", argv[j + 1], pfds[j].fd);

        pfds[j].events = POLLIN;
    

    /* Keep calling poll() as long as at least one file descriptor is
       open. */

    while (num_open_fds > 0)
    
        int ready;

        printf("About to poll()\\n");
        ready = poll(pfds, nfds, -1);
        if (ready == -1)
            errExit("poll");

        printf("Ready: %d\\n", ready);

        /* Deal with array returned by poll(). */

        for (int j = 0; j < nfds; j++)
        
            char buf[10];

            if (pfds[j].revents != 0)
            
                printf("  fd=%d; events: %s%s%s\\n", pfds[j].fd,
                       (pfds[j].revents & POLLIN) ? "POLLIN " : "",
                       (pfds[j].revents & POLLHUP) ? "POLLHUP " : "",
                       (pfds[j].revents & POLLERR) ? "POLLERR " : "");

                if (pfds[j].revents & POLLIN)
                
                    ssize_t s = read(pfds[j].fd, buf, sizeof(buf));
                    if (s == -1)
                        errExit("read");
                    printf("    read %zd bytes: %.*s\\n",
                           s, (int)s, buf);
                
                else
                 /* POLLERR | POLLHUP */
                    printf("    closing fd %d\\n", pfds[j].fd);
                    if (close(pfds[j].fd) == -1)
                        errExit("close");
                    num_open_fds--;
                
            
        
    

    printf("All file descriptors closed; bye\\n");
    exit(EXIT_SUCCESS);

编译程序:

gcc -o main main.c

🎈CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

🎈 感觉有帮助记得「一键三连支持下哦!有问题可在评论区留言💬,感谢大家的一路支持!🤞猿哥将持续输出「优质文章回馈大家!🤞🌹🌹🌹🌹🌹🌹🤞


以上是关于Linux 命令 poll 和 ppoll 详解 + 实例的主要内容,如果未能解决你的问题,请参考以下文章

poll()和ppoll()函数简介

solaris 上的 ppoll

ppoll 中的信号未立即处理

poll

高并发网络编程之epoll详解

epoll详解