C++多线程怎么安全地关闭socket

雨丽大大_3075

雨丽大大_3075

2026-08-06

872人浏览

原创

socket.close() 不可在多线程中直接调用,否则引发未定义行为和崩溃;应先 shutdown() 断流,再由唯一线程安全调用 close(),boost.asio 中须在 io_context 线程内用 cancel() 后 close()。

c++多线程怎么安全地关闭socket

socket.close() 在多线程中直接调用会崩溃

不能在业务线程里直接调用 close()closesocket(),尤其当主线程还在用 recv()send() 或异步操作(如 boost.asio 的 async_read_some())时。系统可能仍在访问已释放的 socket 句柄,触发 WSAENOTSOCKEBADF 或访问违规(access violation)。这不是“偶尔出错”,而是未定义行为——崩溃时机取决于调度和内核状态。

  • Windows 下常见错误码:WSAENOTSOCK(句柄无效)、WSAENOTCONN(连接已关闭但 recv 还在等)
  • Linux 下常见错误码:EBADF(bad file descriptor)、EAGAIN(非阻塞模式下误判为可读)
  • boost.asio 场景下更危险:socket::close() 会取消所有 pending 操作,但回调仍可能在任意线程执行,若回调里再访问已析构的对象,就是典型的 use-after-free

用 shutdown() + close() 分两步断开连接

shutdown() 是安全切断数据流的起点,它不释放句柄,只通知 TCP 层停止收/发,让对方能收到 FIN 包并优雅退出。之后再由唯一持有句柄的线程调用 close()closesocket()

  • 先调 shutdown(sockfd, SHUT_RDWR)(或 SD_BOTH on Windows),确保对端能感知关闭
  • 避免在多个线程重复调 shutdown() —— 它是幂等的,但多次调用无意义且可能干扰状态判断
  • 真正释放资源(即调 close())必须限定在**一个线程内完成**,通常是负责该 socket 生命周期管理的线程(比如 accept 后创建的工作线程,或 io_context 所在线程)
  • 如果用了 boost.asio,优先走 socket::close() 而非原始 close(),因为它会自动处理 pending 操作取消和 error_code 分发

boost.asio 中如何避免 async_read 与 close 竞态

asio 的核心规则是:**所有对同一个 socket 对象的成员函数调用,必须保证线程安全**。这意味着不能一边在 io_context 线程里跑 async_read_some(),一边在业务线程里调 socket::close()

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载
  • 正确做法:用 socket::cancel() 主动取消 pending 操作,再调 socket::close();两者都应在同一 io_context 线程中执行(通过 post() 投递)
  • 示例:io_context.post([&socket] { socket.cancel(); socket.close(); });
  • 不要依赖 error_code 判断是否已关闭——async_read 回调里收到 boost::asio::error::operation_aborted 表示被 cancel,收到 boost::asio::error::eofboost::asio::error::connection_reset 才表示对端关闭
  • 如果 socket 已 move 构造过(比如传给 lambda 捕获),确保它没被提前析构;推荐用 shared_ptr<:socket></:socket> 管理生命周期

RAII + 原子标志控制线程退出路径

socket 关闭往往和线程退出强耦合。线程自己不主动关 socket,而是响应外部信号后,在退出前统一清理。

  • 声明 std::atomic<bool> stop_requested{false};</bool>,所有工作循环都用 while (!stop_requested.load()) 判断
  • 主线程调 stop_requested.store(true) 后,必须 join() 等待线程退出,不能只改标志就不管
  • 线程函数退出前,按顺序做三件事:调 shutdown() → 处理完剩余 recv/send → 最后调 close();每一步都要检查返回值
  • 用 RAII 封装 socket:例如自定义 scoped_socket 类,在析构里调 close(),但前提是确保析构发生在线程安全上下文中(比如线程函数栈展开时)

真正麻烦的从来不是“怎么发关闭指令”,而是“哪个线程、在什么时机、以什么顺序释放 socket 和配套资源”。漏掉一次 shutdown(),或让两个线程同时碰 close(),都可能让服务卡死或静默丢包。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2088

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

959

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

367

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

307

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

366

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

560

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1389

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1177

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1305

9

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习