【网络】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

相关文章

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

Python文件操作与IO流的使用方式

《Python文件操作与IO流的使用方式》:本文主要介绍Python文件操作与IO流的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、python文件操作基础1. 打开文件2. 关闭文件二、文件读写操作1.www.chinasem.cn 读取文件2. 写

使用Python自动化生成PPT并结合LLM生成内容的代码解析

《使用Python自动化生成PPT并结合LLM生成内容的代码解析》PowerPoint是常用的文档工具,但手动设计和排版耗时耗力,本文将展示如何通过Python自动化提取PPT样式并生成新PPT,同时... 目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.