【发布时间】:2015-05-12 16:37:28
【问题描述】:
背景:
我问这个是因为我目前有一个包含许多(成百上千)线程的应用程序。大多数这些线程大部分时间都处于空闲状态,等待将工作项放入队列中。当一个工作项可用时,它会通过调用一些任意复杂的现有代码来处理。在某些操作系统配置中,应用程序会遇到控制最大用户进程数的内核参数,因此我想尝试减少工作线程数量的方法。
我提出的解决方案:
这似乎是一种基于协程的方法,我用协程替换每个工作线程,这将有助于实现这一目标。然后,我可以拥有一个由实际(内核)工作线程池支持的工作队列。当一个项目被放置在特定协程的队列中进行处理时,一个条目将被放置到线程池的队列中。然后它将恢复相应的协程,处理其排队的数据,然后再次挂起,释放工作线程来做其他工作。
实现细节:
在考虑如何做到这一点时,我很难理解无堆栈协程和有堆栈协程之间的功能差异。我有一些使用 Boost.Coroutine 库的堆栈协程的经验。我发现从概念层面理解起来相对容易:对于每个协程,它维护一份 CPU 上下文和堆栈的副本,当您切换到协程时,它会切换到保存的上下文(就像内核模式调度程序一样)。
我不太清楚的是无堆栈协程与此有何不同。在我的应用程序中,与上述工作项排队相关的开销非常重要。我见过的大多数实现,比如the new CO2 library,都表明无堆栈协程提供了开销更低的上下文切换。
因此,我想更清楚地了解无堆栈和堆栈式协程之间的功能差异。具体来说,我想到了这些问题:
References like this one 建议区别在于您可以在堆栈和无堆栈协程中产生/恢复的位置。是这样吗?有没有一个简单的例子说明我可以在堆栈式协程中但不能在无堆栈式协程中做某事?
对使用自动存储变量(即“堆栈上”的变量)是否有任何限制?
我可以从无堆栈协程调用哪些函数有任何限制吗?
如果没有为无堆栈协程保存堆栈上下文,那么协程运行时自动存储变量会去哪里?
【问题讨论】:
-
'大部分线程大部分时间都处于空闲状态,等待将工作项放入队列' - 如果是这种情况,为什么会有这么多线程?
-
@MartinJames:出于遗留原因。我并不是说它是一个好的设计,因此我希望改进它。批量重构整个应用程序不是近期的选择,因此我正在寻找相对简单的改造开始。可能使事情进一步复杂化,对队列的阻塞调用通常在调用堆栈的几个层次上进行(即不在工作线程的顶级函数处)。我认为这将排除在此特定上下文中使用无堆栈线程。
-
另见
boost::asio。
标签: c++ concurrency coroutine boost-coroutine