“runnable thread”的定义是什么,因为它与I / O完成端口的“NumberOfConcurrentThreads”有关?

时间:2012-11-16 11:02:05

标签: c++ winapi boost boost-asio

关于Number of Concurrent Threads in CreateIoCompletionPort的选定答案,我对I / O完成端口文档中“runnable thread”的定义有疑问:

  

当与之关联的可运行线程的总数时   完成端口达到并发值,系统阻塞   执行与该完成相关联的任何后续线程   port,直到可运行线程数低于并发   值。

我理解由于发布完成数据包而从GetQueuedCompletionStatus()唤醒的线程可能因其他原因而发现自己处于睡眠状态(即,它尚未完成其工作且尚未返回呼叫{ {1}},但是正在睡觉,因此 - 如果我理解正确 - 根据上面的定义不是 runnable

我特别想知道的是:假设上面的线程在处理中正在休眠,因为它产生了另一个线程并且正在等待另一个线程完成?

如果线程的子线程处于可运行状态,是否会被认为处于'runnable'状态? -

如果没有,似乎无法从与完成端口关联的线程生成工作线程,而不会冒其他线程将被唤醒的危险,这样运行线程的总数超过GetQueuedCompletionStatus()

例如 - 假设我有50个线程等待NumberOfConcurrentThreads,并发线程数为5,同时发布20个完成数据包,触发非常长的任务,每次线程唤醒执行其中一个任务,它立即产生一个新线程来完成工作,并等待该线程完成长任务,然后再返回调用GetQueuedCompletionStatus()

在这个例子中,20个线程会被唤醒并产生20个并行工作的子线程,还是只有5个线程?

(注意:ADDENDUM:我在我的特定情况下使用Boost.Asio实现了一个工作线程池 - 它在内部利用了I / O完成端口 - 我的工作线程使用JNI调用Java;在内部,Java代码产生自己的工作线程 - 这就是我关心的问题。)

1 个答案:

答案 0 :(得分:1)

寻找这类问题答案的地方总是" Windows Via C/C++ (PRO-Developer)"作者:Jeffrey Richter和Christophe Nasarre。

在我的副本的第327页上,它清楚地解释了I / O完成端口跟踪它从GetQueuedCompletionStatus()(或等效的)调用中释放的线程的线程ID,并将这些线程计为"运行"只要他们不调用任何使他们处于等待状态的功能。

因此,在您的示例中,假设调用GetQueuedCompletionStatus()的线程正在等待由JNI创建的线程,则该线程被视为"未运行"因此IOCP可以从GetQueuedCompletionStatus()释放另一个线程到服务请求。如果你的所有线程最终都会调用JNI并创建另一个线程,那么我认为你的设计有问题,因为你基本上每个事件创建一个"线程"可能无法扩展的设计以及不会创建外部线程的IOCP设计...

它是JNI层的一个函数,它产生了线程,还是纯粹是你正在调用的Java代码?如果后来我建议尽可能重新设计java代码......