背景:
我问这个问题是因为我目前有一个应用程序,其中有很多(数百到数千个)线程。大多数线程在大部分时间内都是空闲的,等待工作项被放入队列中。当工作项可用时,就会通过调用一些任意复杂的现有代码来进行处理。在某些操作系统配置下,应用程序会遇到最大用户进程数的内核参数限制,因此我想尝试通过减少worker线程数量来解决问题。
我的建议解决方案:
似乎采用基于协程的方法,将每个worker线程替换为协程,可以帮助实现这一目标。然后我可以拥有由一组实际(内核)worker线程支持的工作队列。当将一项工作放入特定协程的队列进行处理时,将在线程池的队列中放置一个条目。然后它将恢复相应的协程,处理其排队数据,然后再次挂起它,释放worker线程去做其他工作。
实施细节:
在考虑如何实现这一点时,我很难理解无栈协程和有栈协程之间的功能区别。我有使用Boost.Coroutine库使用有栈协程的经验。从概念层面上来说,我发现它比较容易理解:每个协程都维护CPU上下文和栈的副本,当您切换到一个协程时,它会切换到该保存的上下文(就像内核模式调度程序一样)。
对于无栈协程,对我来说不太清楚它与此的功能区别是什么。在我的应用程序中,与上述工作项排队相关的开销非常重要。我看到大多数实现,例如the new CO2 library建议无栈协程提供更低开销的上下文切换。
因此,我想更清楚地了解无栈协程和有栈协程之间的功能差异。具体而言,我想到以下问题:
像这样的参考文献表明,区别在于你可以在堆栈协程和非堆栈协程中哪里yield/resume。这是真的吗?有没有简单的例子展示在堆栈协程中可以做什么而在非堆栈协程中无法做到?
使用自动存储变量(即“在栈上”的变量)有什么限制吗?
我能从非堆栈协程中调用哪些函数,有限制吗?
如果非堆栈协程不保存堆栈上下文,那么当协程运行时自动存储变量会去哪里?
boost::asio
。 - abhiarora