【问题标题】:What is the definition of "runnable thread" as it relates to the "NumberOfConcurrentThreads" for an I/O completion port?与 I/O 完成端口的“NumberOfConcurrentThreads”相关的“可运行线程”的定义是什么?
【发布时间】:2012-11-16 11:02:05
【问题描述】:

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

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

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

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

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

如果不是,似乎无法从与完成端口关联的线程中生成工作线程,而不会冒其他线程被唤醒的危险,这样正在运行的线程总数超过 NumberOfConcurrentThreads.

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

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

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

【问题讨论】:

    标签: c++ winapi boost boost-asio


    【解决方案1】:

    寻找此类问题答案的地方始终是 Jeffrey Richter 和 Christophe Nasarre 的“Windows Via C/C++ (PRO-Developer)”。

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

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

    它是生成线程的 JNI 层的函数还是纯粹在您调用的 Java 代码中?如果是后者,我建议尽可能重新设计 java 代码...

    【讨论】:

    • 我正在重新设计 Java 层以不产生线程 - 这是我的 Java 类。谢谢!我也会得到你提到的那本书。
    猜你喜欢
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多