C++之poll与epoll总结(一百六十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解poll和epoll用法区别与总结。

2.代码示例

<1>.poll用法讲解

poll函数用于实现多路复用(multiplexing),即通过等待多个文件描述符上的事件发生来进行 I/O 操作,而不阻塞整个程序。它是一种用于实现非阻塞 I/O 的方法,可以提高程序的性能和响应能力。

poll函数的主要作用是监视一组文件描述符(通常是套接字)的状态,并在其中任何一个文件描述符上发生事件时进行相应处理。它可以同时监视多个文件描述符的可读、可写和异常事件。

以下是 poll 函数的一般用法:

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  • fds 是一个指向 pollfd 结构体数组的指针,每个结构体表示一个被监视的文件描述符及其关注的事件。
  • nfdsfds 数组中结构体的数量。
  • timeout 是指定的等待时间,单位是毫秒

<2>.poll代码实例

#include 
#include 
#include 

int main() {
  // 创建 pollfd 数组
  struct pollfd fds[1];

  // 添加需要监听的套接字到 pollfd 数组中
  fds[0].fd = STDIN_FILENO;/* 套接字文件描述符 */;
  fds[0].events = POLLIN; // 监听可读事件

  // 开始监听事件
  while (true) {
    int ret = poll(fds, 1, -1);
    if (ret > 0) {
      if (fds[0].revents & POLLIN) {
	// 可读事件发生在套接字上
	char buffer[256];
	ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
	if (bytesRead > 0) {
	  buffer[bytesRead] = '\0';
	  std::cout << "Received input: " << buffer << std::endl;
	}
      }
    } else if (ret == -1) {
      std::cerr << "Error while polling" << std::endl;
      break;
    }
  }

  return 0;
}

<3>.epoll用法讲解

epoll是一个高效的事件通知机制,用于处理I/O事件。它是Linux操作系统提供的一种异步I/O模型,常用于服务器编程中。其主要作用是监听多个I/O事件,并在发生事件时进行相应的处理。

使用epoll机制可以避免传统的阻塞I/O模型中频繁的轮询操作,提高系统的性能和并发处理能力。它可以管理大量的文件描述符(sockets),并通过回调函数或其他方式提供有效的事件通知机制。当有I/O事件发生时,操作系统会通知应用程序,使得应用程序可以及时处理相关的I/O操作。

epoll通过三个函数epoll_create、epoll_ctl和epoll_wait来完成相关的操作。epoll_create用于创建一个epoll句柄(文件描述符),epoll_ctl用于添加、修改或删除监听的文件描述符,而epoll_wait则是等待事件的发生并进行处理。

总的来说,epoll在C++中的作用是提供高效的异步I/O事件通知机制,使得服务器程序可以高效地处理大量的并发连接和I/O操作。

<4>.epoll实例

#include 
#include 
#include 

#define MAX_EVENTS 10
#define MAX_BUF_SIZE 1024

int main() {
    int epoll_fd, event_count;
    struct epoll_event event, events[MAX_EVENTS];
    char buffer[MAX_BUF_SIZE];

    // 创建epoll句柄
    epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        std::cerr << "Failed to create epoll file descriptor." << std::endl;
        return 1;
    }

    // 设置监听的文件描述符
    event.data.fd = STDIN_FILENO; // 监听标准输入
    event.events = EPOLLIN; // 监听可读事件

    // 将监听事件添加到epoll句柄中
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &event) == -1) {
        std::cerr << "Failed to add file descriptor to epoll." << std::endl;
        close(epoll_fd);
        return 1;
    }

    while (true) {
        // 等待事件发生
        event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (event_count == -1) {
            std::cerr << "Failed to wait for events." << std::endl;
            close(epoll_fd);
            return 1;
        }

        // 处理所有发生的事件
        for (int i = 0; i < event_count; ++i) {
            // 如果是标准输入可读事件
            if (events[i].data.fd == STDIN_FILENO) {
                // 读取用户输入
                int read_count = read(STDIN_FILENO, buffer, MAX_BUF_SIZE);
                if (read_count == -1) {
                    std::cerr << "Failed to read from standard input." << std::endl;
                    close(epoll_fd);
                    return 1;
                }
                // 将读取到的内容打印出来
                std::cout << "Read from standard input: " << buffer << std::endl;
            }
        }
    }

    // 关闭epoll句柄
    close(epoll_fd);
    return 0;
}

你可能感兴趣的:(C++入门系列,c++,开发语言)