与 I/O 完成端口的"NumberOfConcurrentThreads"相关的"runnable thread"的定义是什么?

What is the definition of "runnable thread" as it relates to the "NumberOfConcurrentThreads" for an I/O completion port?

本文关键字:runnable thread 定义 是什么 NumberOfConcurrentThreads      更新时间:2023-10-16

关于CreateIoCompletionPort中并发线程数的选定答案,我有一个关于I/O完成端口文档中"可运行线程"定义的问题:

当与完成端口达到并发值时,系统会阻止与该完成相关联的任何后续线程的执行端口,直到可运行线程的数量降至并发性以下价值

我知道,由于发布了完成数据包而从GetQueuedCompletionStatus()唤醒的线程可能会因为其他原因而处于睡眠状态(即,它尚未完成作业,尚未返回调用GetQueuedCompletionStatus(),但正在睡眠,因此,如果我理解正确,根据上述定义,它不可运行)。

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

如果线程的子线程处于可运行状态,它是否会被视为处于"可运行"状态?

如果没有,则似乎无法从与完成端口相关联的线程派生工作线程,而不冒其他线程将唤醒的危险,因此运行的线程总数超过NumberOfConcurrentThreads

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

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

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

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

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

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

是JNI层的一个函数产生了线程,还是纯粹在您调用的Java代码中?如果以后可能的话,我建议重新设计java代码。。。