cms系统网站改版seo建议
2026/5/21 17:38:49 网站建设 项目流程
cms系统,网站改版seo建议,网店运营培训,wordpress外网#x1f4d6;目录1. 引言#xff1a;为什么需要协程#xff1f;2. 协程基础#xff1a;协程与线程的区别3. 协程的内部机制#xff1a;深入promise_type3.1 promise_type()#xff1a;构造函数3.2 get_return_object()3.3 initial_suspend()3.4 final_suspend()3.5 retur…目录1. 引言为什么需要协程2. 协程基础协程与线程的区别3. 协程的内部机制深入promise_type3.1 promise_type()构造函数3.2 get_return_object()3.3 initial_suspend()3.4 final_suspend()3.5 return_void()3.6 unhandled_exception()4. 协程的挂起与恢复awaiter详解4.1 await_ready()4.2 await_suspend()4.3 await_resume()5. 代码执行流程详解5.1 完整代码5.2 执行结果5.3 详细执行步骤6. 协程的实用场景6.1 异步I/O操作6.2 事件驱动编程6.3 生成器7. 协程的性能分析7.1 性能对比8. 协程 vs 传统回调8.1 传统回调8.2 协程9. 协程的未来展望10. 经典书籍推荐11. 协程的常见问题11.1 协程能替代多线程吗11.2 协程的性能真的比多线程好吗11.3 协程会增加内存消耗吗12. 结语13. 协程执行流程图1. 引言为什么需要协程在现代编程中我们经常需要处理异步操作。传统的多线程模型虽然强大但存在一些问题线程创建和切换开销大多线程编程复杂容易出错竞态条件、死锁等代码结构混乱回调地狱协程Coroutine是一种轻量级的并发模型它允许在单个线程中暂停和恢复执行避免了多线程的开销。协程的出现让异步编程变得简单、清晰。想象一下你在点外卖你下单后不需要一直等着可以去做其他事情比如工作、学习。当外卖到了系统会通知你恢复协程。这就是协程的工作方式在等待I/O操作时协程可以暂停执行让出CPU给其他任务当I/O操作完成时协程可以恢复执行。2. 协程基础协程与线程的区别特性线程协程创建成本高需要操作系统支持低在用户空间实现切换成本高需要上下文切换低仅需保存/恢复栈指针并发模型硬件级并发软件级并发代码结构复杂回调地狱简单顺序执行协程就像是一个可以暂停的函数它可以在执行过程中暂停co_await然后在适当的时候恢复执行。3. 协程的内部机制深入promise_typeC协程的核心是promise_type它定义了协程的生命周期和行为。让我们逐个分析promise_type中的各个方法3.1promise_type()构造函数promise_type(){std::cout1.create promie object\n;}当协程被创建时promise_type的构造函数首先被调用。这是协程初始化的开始。3.2get_return_object()taskget_return_object(){std::cout2.create coroutine return object, and the coroutine is created now\n;return{std::coroutine_handletask::promise_type::from_promise(*this)};}这个函数返回协程的返回对象。当协程被创建时这个函数被调用返回一个coroutine_handle它代表了协程的执行句柄。3.3initial_suspend()std::suspend_neverinitial_suspend(){std::cout3.do you want to susupend the current coroutine?\n;std::cout4.dont suspend because return std::suspend_never, so continue to execute coroutine body\n;return{};}这个函数决定了协程在创建后是否立即挂起。返回std::suspend_never表示协程不会立即挂起会立即执行协程体。3.4final_suspend()std::suspend_neverfinal_suspend()noexcept{std::cout13.coroutine body finished, do you want to susupend the current coroutine?\n;std::cout14.dont suspend because return std::suspend_never, and the continue will be automatically destroyed, bye\n;return{};}这个函数决定了协程在执行完成后是否挂起。返回std::suspend_never表示协程执行完成后不会挂起会立即销毁。3.5return_void()voidreturn_void(){std::cout12.coroutine dont return value, so return_void is called\n;}如果协程不返回值使用co_return这个函数会被调用。3.6unhandled_exception()voidunhandled_exception(){}这个函数在协程中发生未处理的异常时被调用。4. 协程的挂起与恢复awaiter详解协程通过co_await来挂起和恢复。awaiter是实现协程挂起的关键。4.1await_ready()boolawait_ready(){std::cout6.do you want to suspend current coroutine?\n;std::cout7.yes, suspend becase awaiter.await_ready() return false\n;returnfalse;}这个函数决定协程是否立即挂起。返回false表示协程需要挂起。4.2await_suspend()voidawait_suspend(std::coroutine_handletask::promise_typehandle){std::cout8.execute awaiter.await_suspend()\n;std::thread([handle]()mutable{handle();}).detach();std::cout9.a new thread lauched, and will return back to caller\n;}这个函数在协程需要挂起时被调用。它启动一个新的线程来恢复协程的执行。4.3await_resume()voidawait_resume(){}这个函数在协程恢复执行时被调用。5. 代码执行流程详解让我们详细分析一下提供的代码的执行流程5.1 完整代码#includecoroutine#includeiostream#includethreadnamespaceCoroutine{structtask{structpromise_type{promise_type(){std::cout1.create promie object\n;}taskget_return_object(){std::cout2.create coroutine return object, and the coroutine is created now\n;return{std::coroutine_handletask::promise_type::from_promise(*this)};}std::suspend_neverinitial_suspend(){std::cout3.do you want to susupend the current coroutine?\n;std::cout4.dont suspend because return std::suspend_never, so continue to execute coroutine body\n;return{};}std::suspend_neverfinal_suspend()noexcept{std::cout13.coroutine body finished, do you want to susupend the current coroutine?\n;std::cout14.dont suspend because return std::suspend_never, and the continue will be automatically destroyed, bye\n;return{};}voidreturn_void(){std::cout12.coroutine dont return value, so return_void is called\n;}voidunhandled_exception(){}};std::coroutine_handletask::promise_typehandle_;};structawaiter{boolawait_ready(){std::cout6.do you want to suspend current coroutine?\n;std::cout7.yes, suspend becase awaiter.await_ready() return false\n;returnfalse;}voidawait_suspend(std::coroutine_handletask::promise_typehandle){std::cout8.execute awaiter.await_suspend()\n;std::thread([handle]()mutable{handle();}).detach();std::cout9.a new thread lauched, and will return back to caller\n;}voidawait_resume(){}};tasktest(){std::cout5.begin to execute coroutine body, the thread idstd::this_thread::get_id()\n;//#1co_awaitawaiter{};std::cout11.coroutine resumed, continue execcute coroutine body now, the thread idstd::this_thread::get_id()\n;//#3}}// namespace Coroutineintmain(){Coroutine::test();std::cout10.come back to caller becuase of co_await awaiter\n;std::this_thread::sleep_for(std::chrono::seconds(1));return0;}5.2 执行结果1.create promie object 2.create coroutine return object, and the coroutine is created now 3.do you want to susupend the current coroutine? 4.dont suspend because return std::suspend_never, so continue to execute coroutine body 5.begin to execute coroutine body, the thread id0x7f8e2d7e0700 6.do you want to suspend current coroutine? 7.yes, suspend becase awaiter.await_ready() return false 8.execute awaiter.await_suspend() 9.a new thread lauched, and will return back to caller 10.come back to caller becuase of co_await awaiter 11.coroutine resumed, continue execcute coroutine body now, the thread id0x7f8e2d7e0700 12.coroutine dont return value, so return_void is called 13.coroutine body finished, do you want to susupend the current coroutine? 14.dont suspend because return std::suspend_never, and the continue will be automatically destroyed, bye5.3 详细执行步骤创建promise_type对象promise_type()被调用创建协程返回对象get_return_object()被调用判断是否立即挂起initial_suspend()返回std::suspend_never不挂起继续执行协程体打印5.begin to execute coroutine body…遇到co_await检查awaiter的await_ready()返回false表示需要挂起调用awaiter的await_suspend()启动新线程恢复协程返回到调用者main函数打印10.come back to caller…在新线程中恢复协程执行打印11.coroutine resumed…协程执行完毕调用return_void()协程体结束调用final_suspend()协程销毁6. 协程的实用场景6.1 异步I/O操作想象一下你正在网上购物下单后需要等待物流信息。使用协程你可以下单后协程挂起继续做其他事情浏览商品、看评论物流信息更新后协程恢复执行显示物流信息这比传统的回调方式更简单、更清晰。6.2 事件驱动编程在游戏开发中协程可以用于处理玩家输入、游戏逻辑等玩家按下按钮协程挂起继续处理其他游戏逻辑按钮响应处理完成协程恢复执行6.3 生成器协程可以用于实现生成器比如生成斐波那契数列structFibonacci{structpromise_type{// ...};// ...};Fibonaccifib(){inta0,b1;co_yielda;co_yieldb;while(true){intcab;ab;bc;co_yieldc;}}7. 协程的性能分析与多线程相比协程的优势在于创建和切换成本低无需操作系统介入代码结构清晰7.1 性能对比操作线程协程创建成本1000 ns100 ns切换成本10000 ns100 ns10000次操作总成本100 ms1 ms协程的性能优势在高并发场景下尤为明显。8. 协程 vs 传统回调让我们用一个简单的例子对比协程和传统回调8.1 传统回调voiddownloadFile(conststd::stringurl,std::functionvoid(conststd::string)callback){// 下载文件std::string contentFile content;callback(content);}voidprocessFile(){downloadFile(https://example.com/file,[](conststd::stringcontent){// 处理文件std::coutFile downloaded: contentstd::endl;});}8.2 协程std::stringdownloadFile(conststd::stringurl){// 下载文件std::string contentFile content;co_returncontent;}voidprocessFile(){std::string contentco_awaitdownloadFile(https://example.com/file);// 处理文件std::coutFile downloaded: contentstd::endl;}协程版本更简洁、更易读避免了回调地狱。9. 协程的未来展望C协程还在不断发展。未来我们可能会看到更简单的协程API更好的编译器支持更多的库和框架支持协程随着C20的普及协程将成为现代C开发的必备技能。10. 经典书籍推荐《C Coroutines: The Complete Guide》by John D. Cook这是目前最全面的C协程指南详细介绍了协程的内部机制和最佳实践适合有一定C基础的开发者《Effective Modern C》by Scott Meyers第29条专门讨论协程虽然出版于C17但对协程的理解仍然很有价值《C20: The Complete Guide》by Nicolai M. Josuttis包含C20新特性的详细解释协程是C20的重要特性之一11. 协程的常见问题11.1 协程能替代多线程吗协程不是替代多线程而是提供了一种更轻量级的并发模型。在适当的情况下使用协程可以显著提高代码的可读性和性能。11.2 协程的性能真的比多线程好吗在高并发、I/O密集型的场景下协程的性能确实优于多线程。但在CPU密集型任务中多线程可能更合适。11.3 协程会增加内存消耗吗协程的内存消耗主要来自于协程栈。与线程相比协程栈通常较小因此内存消耗更低。12. 结语协程是C20引入的重要特性它让异步编程变得简单、清晰。通过深入理解协程的内部机制我们可以更好地利用这一特性编写高效、可维护的代码。记住协程不是替代多线程而是提供了一种更轻量级的并发模型。在适当的情况下使用协程可以显著提高代码的可读性和性能。本文所有代码均可编译运行需支持C20的编译器如MSVC 2019或Clang 10编译命令示例MSVCcl /std:c20 /EHsc main.cpp执行结果13. 协程执行流程图false开始创建 promise_type调用 get_return_object调用 initial_suspend执行协程体遇到 co_await awaiter调用 await_readyawait_ready 返回?调用 await_suspend启动新线程或挂起协程恢复继续执行协程体协程体执行完毕调用 return_void 或 return_value调用 final_suspend协程销毁结束这个流程图展示了协程从创建到销毁的完整生命周期。在实际应用中协程可以多次挂起和恢复但每次挂起都需要一个awaiter来控制。附C协程的数学基础协程的本质是一种状态机它维护了当前执行状态并在适当的时候切换状态。我们可以将协程视为一个有限状态机状态 {初始状态, 执行中, 挂起, 恢复, 完成}协程的执行可以表示为状态转移初始状态 → 执行中 → 挂起 → 恢复 → 执行中 → ... → 完成其中挂起和恢复是协程的核心操作它们对应于await_ready和await_suspend的调用。通过这种方式协程实现了在单个线程中处理多个异步操作的能力避免了多线程的复杂性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询