操作系统学习笔记——[特殊字符]超详细 | 如何唤醒被阻塞的 socket 线程?线程阻塞原理、线程池、fork/vfork彻底讲明白!

💡超详细 | 如何唤醒被阻塞的 socket 线程?线程阻塞原理、线程池、fork/vfork彻底讲明白!

    • 一、什么是阻塞?为什么线程会阻塞?
    • 二、socket线程被阻塞的典型场景
      • 🧠 解法思路:
    • 三、线程的几种阻塞状态和唤醒方式一览
    • 四、如何判断线程是繁忙还是阻塞?
    • 五、就绪状态线程在等待什么?
    • 六、如何实现线程池?
      • 🏗 线程池原理:
      • 💡 Java 中线程池核心类:
    • 七、fork 和 vfork 的区别?
      • 🧠 补充:写时复制(COW)
    • 八、进阶:写时复制(COW)原理
    • 九、Server 阻塞状态示意
    • 🔚 总结

一、什么是阻塞?为什么线程会阻塞?

线程阻塞是一种等待某个事件发生的状态。比如等待 I/O 完成、锁释放、条件满足、子线程结束等。

常见导致线程阻塞的情况有:

阻塞方式常见场景唤醒方式
Thread.sleep(ms)让出 CPU 一段时间时间到了自动唤醒
Object.wait()等待被 notify()notify() / notifyAll() 唤醒
Thread.join()主线程等待子线程结束子线程执行完毕自动唤醒
LockSupport.park()显式挂起线程调用 unpark(Thread) 唤醒
socket accept() / read()阻塞等待客户端连接/数据客户端连接/发送数据
synchronized 锁竞争等待锁资源锁释放后参与竞争

二、socket线程被阻塞的典型场景

举个最常见的 ServerSocket 场景:

ServerSocket server = new ServerSocket(8888);
Socket client = server.accept(); // 这里会阻塞直到有客户端连接

当执行 accept() 时,线程会阻塞等待客户端连接,直到有连接进入,线程才会被唤醒继续执行。

📌 问题:如果我想手动唤醒这个被阻塞的 accept() 怎么办?

🧠 解法思路:

  1. 关闭 socket:关闭 ServerSocket,会抛出异常从 accept() 中跳出。
  2. 使用 selector/epoll 实现非阻塞,比如 NIO
  3. 新建连接触发 accept() 返回:可以在本地建立一个 loopback 连接触发 accept() 返回。
// 触发唤醒 server.accept()
Socket socket = new Socket("localhost", 8888);

三、线程的几种阻塞状态和唤醒方式一览

阻塞方式描述唤醒方式示例
Thread.sleep()睡眠,释放 CPU,不释放锁时间到Thread.sleep(1000)
Object.wait()等待 notify,释放锁notify()/notifyAll()obj.wait()
Thread.join()等待其他线程结束子线程结束t.join()
Thread.suspend()(已弃用)挂起线程resume()慎用
LockSupport.park()显式挂起unpark()常用于 AQS
socket.accept()阻塞等待连接有连接到来 / 被关闭

四、如何判断线程是繁忙还是阻塞?

  • Linux 可用 ps -e -o pid,state,cmd 查看线程状态:
状态码描述
RRunning(可运行)
SSleeping(可中断阻塞)
DUninterruptible sleep(不可中断阻塞)
ZZombie
TStopped(暂停)

👀 繁忙线程处于 Running 状态
😴 阻塞线程常见为 Sleeping 或 D 状态


五、就绪状态线程在等待什么?

就绪(Runnable)状态的线程,已经满足了运行条件,但等待操作系统调度器为它分配 CPU 才能执行。它处在一个“抢票”的阶段。


六、如何实现线程池?

线程池是一种线程复用机制,用于提高系统并发能力和资源利用率。基本思路如下:

🏗 线程池原理:

  1. 初始化 N 个工作线程,进入等待状态
  2. 维护一个任务队列(生产者-消费者模型)
  3. 有任务时唤醒线程执行,执行完毕后重新等待
  4. 没任务时线程阻塞等待

💡 Java 中线程池核心类:

ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> doTask());

自己实现线程池的基本结构如下:

// 工作线程不断从任务队列中拉取任务
while (true) {Runnable task = taskQueue.take(); // 阻塞等待任务task.run();
}

七、fork 和 vfork 的区别?

特性fork()vfork()
共享地址空间❌ 否✅ 是
复制页表✅ 复制(写时复制)❌ 不复制
父子并发✅ 并发❌ 父进程阻塞等待子进程执行完
安全性高(地址独立)低(共享,容易出错)
速度稍慢更快(节省内存)

🧠 补充:写时复制(COW)

现代 fork() 实现采用 Copy-On-Write 技术,父子进程共享内存页,只有在子进程写入内存时才真正复制,提高效率。


八、进阶:写时复制(COW)原理

  1. fork 后父子共享内存页,只读
  2. 子进程试图写内存 → 触发页保护异常
  3. 内核复制对应页,子进程写副本
  4. 父进程继续使用原来的页

🌟 优点:节省时间和内存,尤其适用于 fork 后马上执行 exec 的情况


九、Server 阻塞状态示意

Client                  Server|                       ||---- connect() ----->  | (accept 阻塞)|                       |====> 唤醒 accept()
  • Server 端 accept() 无客户端连接时处于阻塞状态
  • 被连接时唤醒进入 RUNNABLE
  • 若使用 epoll,Server 线程始终活跃,但非阻塞式等待事件

🔚 总结

本教程详尽梳理了线程阻塞与唤醒机制,尤其是 socket 阻塞处理、线程池设计、fork/vfork 差异 等关键知识点。以下是学习建议:

  • 掌握阻塞类型:主动、被动、锁等待、IO 等
  • 熟练使用 ps/top/jstack 等工具分析线程状态
  • 实践线程池模型:自己写一个简易线程池
  • 深入理解操作系统中的进程管理机制(fork, vfork, exec)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十六届蓝桥杯大赛软件赛省赛 Python 大学 B 组 满分题解

题面链接Htlang/2025lqb_python_b 个人觉得今年这套题整体比往年要简单许多,但是G题想简单了出大问题,预估50101015120860,道阻且长,再接再厉 代码仅供学习参考,满分为赛后洛谷中的测评,蓝桥杯官方测评待…

若依代码生成器原理velocity模板引擎(自用)

1.源码分析 代码生成器:导入表结构(预览、编辑、删除、同步)、生成前后端代码 代码生成器表结构说明: 若依提供了两张核心表来存储导入的业务表信息: gen_table:存储业务表的基本信息 ,它对应于配置代码基本信息和生成信息的页…

如何制定有效的风险应对计划

制定有效的风险应对计划的核心在于: 识别潜在风险、评估风险的影响与概率、选择合适的应对策略、建立动态监控和反馈机制。 其中,识别潜在风险是最为关键的第一步。只有准确识别出可能的风险,才能在后续的评估、应对、监控等环节中做到有的放…

A2A协议实现详解及示例

A2A协议概述 A2A (Agent2Agent) 是Google推出的一个开放协议,旨在使AI智能体能够安全地相互通信和协作。该协议打破了孤立智能体系统之间的壁垒,实现了复杂的跨应用自动化。[1] A2A协议的核心目标是让不同的AI代理能够相互通信、安全地交换信息以及在各…

【中级软件设计师】前趋图 (附软考真题)

【中级软件设计师】前趋图 (附软考真题) 目录 【中级软件设计师】前趋图 (附软考真题)一、历年真题三、真题的答案与解析答案解析 复习技巧: 若已掌握【前趋图】相关知识,可直接刷以下真题; 若对知识一知半解,建议略读题目&#x…

调节磁盘和CPU的矛盾——InnoDB的Buffer Pool

缓存的重要性 无论是用于存储用户数据的索引【聚簇索引、二级索引】还是各种系统数据,都是以页的形式存放在表空间中【对一个/几个实际文件的抽象,存储在磁盘上】如果需要访问某页的数据,就会把完整的页数据加载到内存中【即使只访问页中的一…

springboot和springcloud的区别

1. ‌目的与功能‌ ‌1)Spring Boot‌: 主要用于快速构建独立的、生产级的 Spring 应用程序。它通过自动配置和嵌入式服务器等特性,简化了微服务的开发、启动和部署,使开发者能够专注于业务逻辑而非繁琐的配置。‌Spring Boot是一个快速开发的框架,旨在简化Java应用程序的开…

耘想WinNAS:以聊天交互重构NAS生态,开启AI时代的存储革命

一、传统NAS的交互困境与范式瓶颈 在传统NAS(网络附加存储)领域,用户需通过复杂的图形界面或命令行工具完成文件管理、权限配置、数据检索等操作,学习成本高且效率低下。例如,用户若需搜索特定文件,需手动…

在断网的时候,websocket 一直在CLOSING 状态

现象 websocket 先连接成功,然后断网。 由于维护了一套心跳机制,前端发起心跳,如果一段时间内没有收到服务端返回的心跳。则表示连接断开。 用心跳的方式处理断网的兜底情况。 然而,此时网络是断开的,在代码中直接调…

基于AWS的大模型调用场景:10大成本优化实战方案

大模型训练与推理是AI领域的计算密集型场景,如何在AWS上实现高性能与低成本的双重目标?本文从实例选型、弹性伸缩、存储优化等角度,分享10个经过验证的AWS成本优化策略,帮助企业节省30%以上成本。 一、大模型场景的成本痛点分析 计…

【网络原理】TCP/IP协议五层模型

目录 一. 协议的分层 二. OSI七层网络协议 三. TCP/IP五层网络协议 四. 网络设备所在分层 五. 封装 六. 分用 七. 传输中的封装和分用 八. 数据单位术语 一. 协议的分层 常见的分层为两种OSI七层模型和TCP/IP五层模型 为什么要协议分层? 在网络通信中&…

科技快讯 | 阿里云百炼MCP服务上线;英伟达官宣:CUDA 工具链将全面原生支持 Python

李飞飞团队最新AI报告:中美模型性能差距近乎持平 4月8日,斯坦福大学以人为本人工智能研究所发布《2025年人工智能指数报告》。报告显示,2023年AI性能显著提升,AI应用加速,投资增长,中美AI模型差距缩小。报告…

猫咪如厕检测与分类识别系统系列【三】融合yolov11目标检测

✅ 前情提要 家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠…

2025年燃气证书:传承与发展的行业纽带

回溯历史长河,能源的利用与人类文明的发展息息相关。从远古时期的钻木取火,到如今广泛应用的燃气能源,每一次能源的变革都推动着社会的巨大进步。而在现代燃气行业蓬勃发展的背后,燃气从业人员资格证书正扮演着传承与发展的重要纽…

在Ubuntu下进行单片机开发是否需要关闭Secure Boot

1. Secure Boot的作用 功能:Secure Boot是UEFI的安全功能,旨在阻止未经验证的驱动或操作系统启动,防止恶意软件篡改引导过程。 影响范围:它主要限制的是操作系统启动阶段加载的内核级驱动(如显卡驱动、虚拟化模块&…

国达陶瓷重磅推出陶瓷罗马柱外墙整装尖端新产品“冠岩臻石”

近日,记者在佛山国达建材有限公司(以下简称国达陶瓷)董事长杨建平处了解到,该公司重磅推出的“冠岩臻石”新产品,是属于陶瓷罗马柱外墙整装产品中的尖端产品。新产品自面市之后,深受高端用户的青睐与认可。…

【分享】Ftrans文件摆渡系统:既保障传输安全,又提供强集成支持

【分享】Ftrans文件摆渡系统:既保障传输安全,又提供强集成支持! 在数字化浪潮中,企业对数据安全愈发重视,网络隔离成为保护核心数据的关键防线,比如隔离成研发网-办公网、生产网-测试网、内网-外网等。网络…

实验一 字符串匹配实验

一、实验目的 1.熟悉汇编语言编程环境和DEBUG调试程序的使用。 2.掌握键盘输入字符串的方法和分支程序的设计。 二、实验内容 编程实现:从键盘分别输入两个字符串,然后进行比较,若两个字符串的长度…

添加登录和注册功能

先写前端再写后端 前提&#xff1a;ideavue3mybatisspringBoot3前后端分离实现对一张表的增删改查&#xff08;完整代码版&#xff09;-CSDN博客 项目地址 1.添加一个Login.vue视图 <template><div class"login_container"><div class"login…

【Windows】系统安全移除移动存储设备指南:告别「设备被占用」弹窗

Windows系统安全移除移动存储设备指南&#xff1a;告别「设备被占用」弹窗 解决移动硬盘和U盘正在被占用无法弹出 一、问题背景 使用Windows系统时&#xff0c;经常遇到移动硬盘/U盘弹出失败提示「设备正在使用中」&#xff0c;即使已关闭所有可见程序。本文将系统梳理已验证…