关于CreateIoCompletionPort 中并发线程数的选定答案,我对 I/O 完成端口文档中“可运行线程”的定义有疑问:
当与完成端口关联的可运行线程的总数达到并发值时,系统会阻止与该完成端口关联的任何后续线程的执行,直到可运行线程的数量下降到并发值以下。
我了解GetQueuedCompletionStatus()
由于发布完成数据包而被唤醒的线程可能会由于其他原因而发现自己处于睡眠状态(即,它尚未完成其工作并且尚未返回调用GetQueuedCompletionStatus()
,但正在睡眠,因此 - 如果我正确理解 -根据上述定义无法运行)。
我特别想知道的是:假设上面的线程在其处理过程中正在休眠,因为它产生了另一个线程并正在等待另一个线程完成?
如果线程的子线程处于可运行状态,该线程是否会被视为处于“可运行”状态?
如果没有,似乎无法从与完成端口关联的线程中生成工作线程,而不冒其他线程将被唤醒的危险,这样运行线程的总数就会超过NumberOfConcurrentThreads
.
例如 - 假设我有 50 个线程在等待GetQueuedCompletionStatus()
,并发线程数为 5,同时发布 20 个完成数据包触发非常长的任务,并且每次线程唤醒执行其中一个任务时,它立即产生一个新的线程完成工作并等待该线程完成长任务,然后再次返回调用GetQueuedCompletionStatus()
。
在这个例子中,20 个线程会被唤醒并产生 20 个并行工作的子线程,还是只有 5 个线程?
(注意:附录:在我的特定情况下,我正在使用 Boost.Asio 实现一个工作线程池 - 它在内部利用 I/O 完成端口 - 我的工作线程使用 JNI 调用 Java;在内部,Java 代码产生了自己的工作线程 - 所以这是我关心的问题。)