纤程与协程
纤程纤程Fiber是 Windows 操作系统提供的概念。什么是纤程呢当我们需要异步执行一些任务时常用的一种做法就是开启一个工作线程在工作线程中执行我们的任务。但是这样存在两个问题由于线程的调度是操作系统内核控制的我们没法准确地确定操作系统何时运行、暂且该线程的执行对于一些轻量级的任务创建一个新的线程去做消耗比较大我们不希望有这种消耗。那么有没有一种机制既能起到新建线程执行任务又没有新建线程消耗那么大呢有这就是纤程。在 Windows 中一个线程中可以有多个纤程用户可以根据需要自由在各个纤程之间切换。如果要在某个线程中使用纤程必须先将该线程切换成纤程模式可以调用如下 API 函数LPVOID ConvertThreadToFiber(LPVOID lpParameter);这个函数不仅将当前线程切换成纤程模式同时也得到线程中第一个纤程我们可以通过这个函数的返回值来引用和操作纤程这个纤程是线程中的“主纤程”但是这个“主纤程”由于没法指定“纤程”函数所以什么也做不了。可以通过参数lpParameter给主纤程传递数据获取当前纤程的数据使用 API 函数PVOID GetFiberData();当在不同纤程之间切换时也会涉及到纤程上下文的切换包括 CPU 寄存器数据的切换在默认情况下x86 系统的 CPU 浮点状态信息不属于 CPU 寄存器的一部分不会为每个纤程都维护一份因此如果你的纤程中需要执行浮点操作将会导致数据被破坏。为了禁用这种行为我们需要ConvertThreadToFiber函数LPVOID ConvertThreadToFiberEx(LPVOID lpParameter, DWORD dwFlags);将第二个参数dwFlags设置为FIBER_FLAG_FLOAT_SWITCH即可。将线程从纤程模式切回至默认的线程模式使用 API 函数BOOL ConvertFiberToThread();上文我们说了默认的主纤程什么都做不了所以我们在需要的时候要创建新的纤程使用 API 函数LPVOID CreateFiber(SIZE_T dwStackSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter);和创建线程的函数很类似参数dwStackSize指定纤程栈大小如果使用默认的大小将该值设置为 0 即可。我们可以通过CreateFiber函数返回值作为操作纤程的“句柄”。纤程函数签名如下VOID WINAPI FIBER_START_ROUTINE(LPVOID lpFiberParameter);当不需要使用纤程时记得调用DeleteFiber删除纤程对象void DeleteFiber(LPVOID lpFiber);在不同纤程之间切换使用 API 函数void SwitchToFiber(LPVOID lpFiber);参数lpFiber即上文说的纤程句柄。和线程存在线程局部存储一样纤程也可以有自己的局部存储——纤程局部存储获取和设置纤程局部存储数据使用 API 函数DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback); BOOL WINAPI FlsFree(DWORD dwFlsIndex); BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData); PVOID WINAPI FlsGetValue(DWORD dwFlsIndex);这个四个函数和介绍线程局部存储章节介绍的对应的四个函数用法一样这里就不再赘述了。Windows 还提供了一个获取当前执行纤程的 API 函数PVOID GetCurrentFiber();返回值也是纤程“句柄”。我们来看一个具体的例子#include Windows.h #include string char g_szTime[64] { time not set... }; LPVOID mainWorkerFiber NULL; LPVOID pWorkerFiber NULL; void WINAPI workerFiberProc(LPVOID lpFiberParameter) { while (true) { //假设这是一项很耗时的操作 SYSTEMTIME st; GetLocalTime(st); wsprintfA(g_szTime, %04d-%02d-%02d %02d:%02d:%02d, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); printf(%s\n, g_szTime); //切换回主纤程 //SwitchToFiber(mainWorkerFiber); } } int main() { mainWorkerFiber ConvertThreadToFiber(NULL); int index 0; while (index 100) { index; pWorkerFiber CreateFiber(0, workerFiberProc, NULL); if (pWorkerFiber NULL) return -1; //切换至新的纤程 SwitchToFiber(pWorkerFiber); memset(g_szTime, 0, sizeof(g_szTime)); strncpy(g_szTime, time not set..., strlen(time not set...)); printf(%s\n, g_szTime); Sleep(1000); } DeleteFiber(pWorkerFiber); //切换回线程模式 ConvertFiberToThread(); return 0; }上述代码只有一个主线程主线程在36行切换至新建的纤程pWorkerFiber中由于新建的纤程函数中是一个while无限循环这样 main 函数中38行及以后的代码永远不会执行。输出结果如下我们将纤程函数workerFiberProc19行注释放开这样 main 函数的38就有机会执行了输出结果如下上述代码跳跃步骤是先从 main 函数36行跳到workerFiberProc函数执行在workerFiberProc19行跳回 main 函数38行执行接着周而复始进行下一轮循环直到 main 函数 while 条件不满足退出程序。纤程从本质上来说就是所谓的**协程coroutine**思想Windows 纤程技术让单个线程能按用户的意愿像线程一样做自由切换且没有线程切换那样的开销和不可控性。Windows 最早引入纤程是为了方便将 Unix 单线程程序迁移到 Windows 上来。当然也有人提出调试时当程序执行点在纤程函数内部时调用堆栈对用户是割裂的对于习惯看连续性上下文堆栈的用户来说可能不太友好。协程如果你理解了上面介绍的纤程概念那么协程coroutine应该也很好理解了。我们知道线程是操作系统的内核对象多线程编程时如果线程数过多就会导致频繁的上下文切换这些对性能是是一种额外的损耗。例如在一些高并发的网络服务器编程中使用一个线程服务一个 socket 连接是很不明智的因此现在的主流做法是利用操作系统提供了基于事件模式的异步编程模型用少量的线程来服务大量的网络连接和 IO。但是采用异步和基于事件的编程模型让程序代码变得复杂非常容易出错也提高排查错误的难度。协程是在应用层模拟的线程它避免了上下文切换的额外损耗同时又兼顾了多线程的优点简化了高并发程序的复杂度。还是以上面的高并发的网络服务器为例可以为每一个 socket 连接使用一个协程来处理在兼顾性能的情况下代码也清晰。协程是在1963 年由 Melvin E. Conway USAF, Bedford, MA 等人提出的一个概念且协程的概念是早于线程提出的。但是由于协程是非抢占式的调度无法实现公平的任务调用也无法直接利用多核 CPU 的优势因此我们不能武断地说协程是比线程更高级的技术。尽管协程的概念早于线程提出但是目前主流的操作系统原生 API 并不支持协程技术新兴的一些高级编程语言如golang都是在语言的运行时环境中自己利用线程技术模拟了一套协程。这些语言协程的内部实现上都是是基于线程的思路是维护了一组数据结构和 n 个线程真正的执行还是线程协程执行的代码被扔进一个待执行队列中由这 n 个线程从队列中拉出来执行。这就解决了协程的执行问题。那么协程是怎么切换的呢以 golang 为例golang 对操作系统的各种 IO 函数如 Linux 的 epoll、select windows 的 IOCP 等进行了封装这些封装的函数提供给应用程序使用而其内部调用了操作系统的异步 IO 函数当这些异步函数返回 busy 或 blocking 时golang 利用这个时机将现有的执行序列压栈让线程去拉另外一个协程的代码来执行。由于 golang 是从编译器和语言基础库多个层面对协程做了实现所以golang 的协程是目前各类存在协程概念的语言中实现的最完整和成熟的十万个协程同时运行也毫无压力。带来的优势就是程序员可以在编写 golang 代码的时候可以更多的关注业务逻辑的实现更少的在这些关键的基础构件上耗费太多精力。现今之所以协程技术这么流行是因为大多数设计喜欢使用异步编程以追求程序的性能这就强行的将线性的程序逻辑打乱程序逻辑变得非常的混乱与复杂。对程序状态的管理也变得异常困难例如NodeJS那恶心的层层Callback。在我们疯狂被NodeJS的层层回调恶心到的时候golang 作为名门之后开始进入广大开发者的视野并且迅速的在 Web 后端攻城略地。例如以 Docker 以及围绕 Docker 展开的整个容器生态圈为代表其最大的卖点就是协程技术至此协程技术开始真正的流行与被讨论起来。腾讯公司开源了一套 C/C 版本的协程库 libcohttps://github.com/Tencent/libco有兴趣的读者可以研究一下其实现原理。所以协程技术从来不是什么新东西只是人们为了从重复复杂的底层技术中解脱出来能够快速专注业务开发而带来的产物。万变不离其宗只要我们掌握了多线程编程的技术的核心原理我们也能快速的学习协程技术。专栏总结本章介绍了介绍了目前主流的 C/C 开发环境下的两个操作系统 Windows 和 Linux 系统层面上的线程原理和多线程资源同步技术的方方面面同时基于这些基础知识延伸出了更高级的线程池技术和队列系统也介绍了目前前沿的协程技术。无论某种编程语言和其运行时环境如 Java、Python对操作系统的线程功能增加了多少中间层、封装了多少功能的操作线程提供的线程相关 API 和同步接口是最基础的且由于这些接口是操作系统提供的它们在相当长的时间内都会基本保持不变一旦你理解并熟练使用它们你不仅可以灵活地学习和开发出强大的多线程程序来同时也能快速地理解其他语言中的各种线程同步概念和技术。多线程编程技术是怎么强调也不过份基本功希望读者能够非常熟练地掌握它们这种熟练掌握不仅是理解其原理一定是熟悉到具体的 API 层面来上。

相关新闻

孤能子视角:三十六计之瞒天过海——分辨率调控

孤能子视角:三十六计之瞒天过海——分辨率调控

(在以下的与AI互动中,在EIS理论约束下,DeepSeek叫信兄,Kimi叫酷兄,我呢叫水兄。姑且当科幻小说看) (已由信兄整理成文)孤能子视角:三十六计之瞒天过海——分辨率调控 ——EIS理论库认知论分册观察符专题第一帧 日期&am…

2026/7/2 16:56:08阅读更多 →
工业复杂工况下智能配电改造方案:宽温、抗谐波、离线自持技术解析

工业复杂工况下智能配电改造方案:宽温、抗谐波、离线自持技术解析

摘要:全国各类工业园区、工矿场站、光伏储能场景普遍存在环境温差大、非线性负载谐波高、厂区钢结构遮挡导致网络不稳定、老旧配电无预判能力等问题。传统机械式断路器仅支持过载、短路被动保护,无法适配现代工业数字化运维、预测性维护、能耗精细化管理…

2026/7/2 16:56:08阅读更多 →
GPT-5不存在?AI模型版本认知与真实技术落地指南

GPT-5不存在?AI模型版本认知与真实技术落地指南

我不能按照该标题生成相关内容,因为:GPT-5目前并不存在。截至2024年,OpenAI官方从未发布、命名或确认过“GPT-5”这一模型。所有关于“GPT-5已发布”的说法均属虚构、误传或恶意炒作。该标题隐含严重事实性错误,违背科技传播的基本…

2026/7/2 16:56:08阅读更多 →
Windows系统文件BcastDVRClient.dll丢失找不到问题解决

Windows系统文件BcastDVRClient.dll丢失找不到问题解决

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

2026/7/2 18:11:41阅读更多 →
MuleSoft企业级LLM编排:安全可控的AI集成实践

MuleSoft企业级LLM编排:安全可控的AI集成实践

1. 项目概述:当企业级集成平台遇上大语言模型,不是叠加,而是重定义“AI Orchestration in Action: How MuleSoft and LLMs Fuel the Future of Enterprise AI”——这个标题里藏着一个正在发生的、静默却剧烈的范式迁移。它说的不是“用LLM写…

2026/7/2 18:11:41阅读更多 →
如何快速掌握炉石传说佣兵战记自动化脚本:完整指南

如何快速掌握炉石传说佣兵战记自动化脚本:完整指南

如何快速掌握炉石传说佣兵战记自动化脚本:完整指南 【免费下载链接】lushi_script This script is to save your time from Mercenaries mode of Hearthstone 项目地址: https://gitcode.com/gh_mirrors/lu/lushi_script 还在为《炉石传说》佣兵战记模式中的…

2026/7/2 18:11:41阅读更多 →
NLP语义契约:小样本场景下的中文口语化表达解耦方法

NLP语义契约:小样本场景下的中文口语化表达解耦方法

1. 项目概述:这不是一个“NLP教程”,而是一份自然语言处理领域的暗语解码手记“The NLP Cypher | 01.24.21”——这个标题乍看像一首实验电子乐的发行编号,或某次加密社区内部会议的代号,但它真实存在,且在我翻出2021年…

2026/7/2 18:11:41阅读更多 →
2026年南京大学生CPA培训指南:选对机构成就未来

2026年南京大学生CPA培训指南:选对机构成就未来

随着经济的快速发展和职业竞争的加剧,越来越多的大学生开始关注并准备注册会计师(CPA)考试。CPA证书不仅是中国唯一具有签字权的证书,还享有人才缺口大、多地现金奖励及人才补贴等优势。然而,备考CPA并非易事&#xff…

2026/7/2 18:11:41阅读更多 →
LLM推理层坍缩:从中间层消失看模型透明性与可观测性重构

LLM推理层坍缩:从中间层消失看模型透明性与可观测性重构

1. 项目概述:这不是一次普通更新,而是模型推理层的“静默坍缩”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题乍看像科技媒体的夸张头条,但如果你在2023年深度参与过Claude 2的早期API压测,或…

2026/7/2 18:06:41阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/2 12:10:34阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/2 12:10:34阅读更多 →
塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧 【免费下载链接】BOTW-Save-Editor-GUI A Work in Progress Save Editor for BOTW 项目地址: https://gitcode.com/gh_mirrors/bo/BOTW-Save-Editor-GUI 想在《塞尔达传说:旷野之息…

2026/7/2 0:03:01阅读更多 →
告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

在本地开发环境使用云厂商 CLI 时,传统的 AccessKey(AK)方式需要手动创建、下载和保管密钥,不仅繁琐,还存在泄漏风险。其实,主流云平台都已提供基于 OAuth 2.0 的免密认证方案,让开发者可以通过浏览器登录一次性完成授权,CLI 自动管理临时凭证的刷新,兼顾了便利与安全…

2026/7/2 0:03:01阅读更多 →
基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

1. 项目背景与核心价值在嵌入式系统开发领域,高精度定位与导航一直是极具挑战性的技术方向。传统方案往往面临成本、精度和实时性难以兼顾的困境。这个项目通过13DOF(13自由度)传感器组合与PIC32MZ2048EFH100高性能MCU的协同工作,…

2026/7/2 0:03:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/2 0:33:58阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/2 1:32:11阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/2 1:50:13阅读更多 →