0

0

c++怎么操作IO多路复用select_c++ IO多路复用select方法

穿越時空

穿越時空

发布时间:2025-10-07 12:32:02

|

423人浏览过

|

来源于php中文网

原创

C++中使用select实现IO多路复用,通过调用select()函数监控多个文件描述符的读写状态,结合fd_set宏操作管理集合,示例程序监听socket和标准输入,每次循环重置集合并调用select等待事件,支持超时机制,但存在性能瓶颈和fd数量限制,适用于小型或跨平台项目。

c++怎么操作io多路复用select_c++ io多路复用select方法

在C++中使用IO多路复用的 select 方法,主要是通过调用操作系统提供的 select() 系统函数来实现。它允许程序同时监控多个文件描述符(如socket、标准输入等),判断哪些已经准备好进行读、写或出现异常事件。这对于编写高性能网络服务器或需要处理多个并发连接的程序非常有用。

select 函数基本用法

select() 的函数原型定义在 头文件中:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数说明:

  • nfds:所有被监控的文件描述符中最大值加1(即从0到nfds-1)
  • readfds:监听可读事件的文件描述符集合
  • writefds:监听可写事件的文件描述符集合
  • exceptfds:监听异常事件的文件描述符集合
  • timeout:等待超时时间,可以设为阻塞(NULL)、非阻塞(tv_sec=0, tv_usec=0)或指定超时

fd_set 集合操作宏

select 使用 fd_set 类型来管理文件描述符集合,配合以下宏操作:

立即学习C++免费学习笔记(深入)”;

10Web
10Web

AI驱动的WordPress网站自动构建器,托管和页面速度助推器

下载
  • FD_ZERO(fd_set *set):清空集合
  • FD_SET(int fd, fd_set *set):将文件描述符加入集合
  • FD_CLR(int fd, fd_set *set):从集合中移除文件描述符
  • FD_ISSET(int fd, fd_set *set):检查文件描述符是否在集合中(select 返回后使用)

C++ 示例:监听标准输入和 socket

下面是一个简单的 C++ 示例,演示如何使用 select 监听标准输入和一个 socket 连接:

#include iostream>
#include
#include
#include
#include
#include

int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};

// 创建 socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);

bind(server_fd, (struct sockaddr *)&address, sizeof(address));
listen(server_fd, 3);

std::cout new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen);

fd_set readfds;
struct timeval timeout;

while (true) {
// 每次循环都要重新设置 fd_set
FD_ZERO(&readfds);
FD_SET(new_socket, &readfds);
FD_SET(STDIN_FILENO, &readfds); // 监听标准输入

int max_fd = (new_socket > STDIN_FILENO ? new_socket : STDIN_FILENO) + 1;

timeout.tv_sec = 5;
timeout.tv_usec = 0;

int activity = select(max_fd, &readfds, nullptr, nullptr, &timeout);

if (activity std::cerr break;
} else if (activity == 0) {
std::cout continue;
}

// 检查 socket 是否可读
if (FD_ISSET(new_socket, &readfds)) {
int valread = read(new_socket, buffer, 1024);
if (valread std::cout break;
}
std::cout memset(buffer, 0, 1024);
}

// 检查标准输入是否可读
if (FD_ISSET(STDIN_FILENO, &readfds)) {
std::string input;
std::getline(std::cin, input);
const char* msg = input.c_str();
send(new_socket, msg, strlen(msg), 0);
}
}

close(new_socket);
close(server_fd);
return 0;
}

注意事项与局限性

尽管 select 是跨平台兼容性较好的 IO 多路复用方式,但也有明显缺点:

  • 每次调用 select 都需要重新设置 fd_set 集合
  • 文件描述符数量受限(通常最多 1024)
  • 需要遍历所有监听的 fd 来检查状态变化,效率随 fd 数量增加而下降
  • 每次都要传递最大 fd + 1,开销较大

在 Linux 下,更推荐使用 pollepoll 实现更高性能的多路复用。

基本上就这些。select 虽然古老,但在小型项目或跨平台场景下仍很实用。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

229

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

434

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

713

2023.08.22

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

81

2023.09.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

519

2023.09.20

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

116

2025.10.15

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

253

2025.10.24

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.4万人学习

Git 教程
Git 教程

共21课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号