【网络】socket套接字结合IO多路复用

2024-05-26 02:12

本文主要是介绍【网络】socket套接字结合IO多路复用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

在多线程编程中,I/O 多路复用(如 selectpollepoll)可以与多线程结合使用,以提高系统的并发处理能力和效率。结合多线程和 I/O 多路复用,可以实现高性能的网络服务器和客户端。以下是一些常见的多线程和 I/O 多路复用结合使用的策略和示例:

常见策略

  1. 单线程使用 I/O 多路复用:
    在一个单独的线程中使用 I/O 多路复用来监视所有的文件描述符。当有文件描述符变得就绪时,在该线程中处理 I/O 操作。这种方法简单且易于实现,但可能会因为单线程的处理能力受限,无法充分利用多核 CPU 的性能。

  2. 多线程使用 I/O 多路复用:
    在主线程中使用 I/O 多路复用来监视所有的文件描述符。当有文件描述符变得就绪时,调用或创建线程来处理 I/O 操作。这种多线程与 I/O 多路复用相结合的方式,可以提高服务器的并发处理能力,充分利用多核 CPU 的性能,是实现高性能网络服务器的一种有效方法。

示例代码

下面是一个简单的例子,展示了如何在多线程环境中结合使用 I/O 多路复用和工作线程池来处理网络连接:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>#define PORT 8080
#define MAX_CLIENTS 30std::mutex queue_mutex;
std::condition_variable condition;
std::queue<int> client_queue;void worker_thread() {while (true) {std::unique_lock<std::mutex> lock(queue_mutex);condition.wait(lock, []{ return !client_queue.empty(); });int client_socket = client_queue.front();client_queue.pop();lock.unlock();char buffer[1024] = {0};int valread = read(client_socket, buffer, 1024);if (valread > 0) {buffer[valread] = '\0';//可对字符串进行处理send(client_socket, buffer, valread, 0);}close(client_socket);}
}int main() {int server_fd, new_socket;struct sockaddr_in address;fd_set readfds;int client_sockets[MAX_CLIENTS] = {0};server_fd = socket(AF_INET, SOCK_STREAM, 0);address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);bind(server_fd, (struct sockaddr*)&address, sizeof(address));listen(server_fd, 3);// 创建工作线程池std::vector<std::thread> workers;for (int i = 0; i < 4; ++i) {workers.emplace_back(worker_thread);}while (true) {FD_ZERO(&readfds);FD_SET(server_fd, &readfds);int max_sd = server_fd;for (int i = 0; i < MAX_CLIENTS; i++) {int sd = client_sockets[i];if (sd > 0)FD_SET(sd, &readfds);if (sd > max_sd)max_sd = sd;}int activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);if (FD_ISSET(server_fd, &readfds)) {new_socket = accept(server_fd, NULL, NULL);for (int i = 0; i < MAX_CLIENTS; i++) {if (client_sockets[i] == 0) {client_sockets[i] = new_socket;break;}}}for (int i = 0; i < MAX_CLIENTS; i++) {int sd = client_sockets[i];if (FD_ISSET(sd, &readfds)) {std::unique_lock<std::mutex> lock(queue_mutex);client_queue.push(sd);lock.unlock();condition.notify_one();client_sockets[i] = 0;}}}for (std::thread &worker : workers) {worker.join();}return 0;
}

代码解释

  • 主线程: 主线程负责使用 select 监视服务器套接字和已连接的客户端套接字。select 函数返回就绪的套接字后,主线程将新的客户端连接或已就绪的客户端套接字加入任务队列,并通知工作线程池处理这些套接字。

  • 工作线程池: 多个工作线程从任务队列中获取套接字,并处理 I/O 操作,如读取数据、发送响应和关闭连接。

  • 同步机制: 使用 std::mutexstd::condition_variable 实现线程间的同步,确保安全地访问和修改任务队列。

这篇关于【网络】socket套接字结合IO多路复用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003269

相关文章

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

Python结合Free Spire.PDF for Python实现PDF页面旋转

《Python结合FreeSpire.PDFforPython实现PDF页面旋转》在日常办公或文档处理中,我们经常会遇到PDF页面方向错误的问题,本文将分享如何用Python结合FreeSpir... 目录基础实现:单页PDF精准旋转完整代码代码解析进阶操作:覆盖多场景旋转需求1. 旋转指定角度(90/27

Java通过ServerSocket与Socket实现通信过程

《Java通过ServerSocket与Socket实现通信过程》本文介绍了Java中的ServerSocket和Socket类,详细讲解了它们的构造方法和使用场景,并通过一个简单的通信示例展示了如何... 目录1 ServerSocket2 Socket3 服务器端4 客户端5 运行结果6 设置超时总结1

浅析Python中如何处理Socket超时

《浅析Python中如何处理Socket超时》在网络编程中,Socket是实现网络通信的基础,本文将深入探讨Python中如何处理Socket超时,并提供完整的代码示例和最佳实践,希望对大家有所帮助... 目录开篇引言核心要点逐一深入讲解每个要点1. 设置Socket超时2. 处理超时异常3. 使用sele

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

Python实现简单封装网络请求的示例详解

《Python实现简单封装网络请求的示例详解》这篇文章主要为大家详细介绍了Python实现简单封装网络请求的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装依赖核心功能说明1. 类与方法概览2.NetHelper类初始化参数3.ApiResponse类属性与方法使用实

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

Go中select多路复用的实现示例

《Go中select多路复用的实现示例》Go的select用于多通道通信,实现多路复用,支持随机选择、超时控制及非阻塞操作,建议合理使用以避免协程泄漏和死循环,感兴趣的可以了解一下... 目录一、什么是select基本语法:二、select 使用示例示例1:监听多个通道输入三、select的特性四、使用se