在MSDN documentation中查找CreateIoCompletionPort
,我们读到:
但是,我发现的文档没有表明IoCompletionPort
实际上创建了任何线程。
实际上,Microsoft提供的example使用以下代码来确定有多少个处理核心可用(而不是将0
传递给NumberOfConcurrentThreads
),然后实际上创建了那么多线程。
// The general value of the thread count is the system's processor count.
SYSTEM_INFO sysInfo = { 0 };
GetNativeSystemInfo(&sysInfo);
const DWORD dwThreadCount = sysInfo.dwNumberOfProcessors;
// A class in the example that wraps around IoCompletionPort
IOCompletionPort port;
// Construct the thread pool
HANDLE* hThreads = new HANDLE[dwThreadCount];
for (DWORD i = 0; i < dwThreadCount; ++i) {
// The threads run CompletionThread
hThreads[i] = CreateThread(0, 0, IOCompletionThread, &port, 0, NULL);
}
在我看来,这表明某种程度上存在与
IoCompletionPort
相关的“承载能力”。但是,这表现如何?我很难理解如何(或什至为何如此)可访问完成端口的线程如何防止从完成端口出队。实际上,我尝试将创建线程的行修改为
new HANDLE[++dwThreadCount]
(并从声明中删除了const
说明符),并且该示例似乎可以毫无提示地执行。我只是在执行结束时注意到一个额外的超时错误。我目前唯一的结论就是说
NumberOfConcurrentThreads
是一个“虚拟”变量,没有实际用途,那么我会缺少什么呢? 最佳答案
IOCP基于 KQUEUE
object:
struct KQUEUE {
DISPATCHER_HEADER Header;
LIST_ENTRY EntryListHead;
ULONG CurrentCount;
ULONG MaximumCount;
LIST_ENTRY ThreadListHead;
};
如果由
MaximumCount
(计数== 0)初始化,则由KeNumberProcessors
分配KeInitializeQueue
;如果是从CreateIoCompletionPort(ZwCreateIoCompletion)初始化,则由NumberOfConcurrentThreads
分配。CurrentCount
是绑定(bind)到此KQUEUE
的“ Activity ”(未等待)线程的数量(在ETHREAD
结构中有一个特殊字段:KQUEUE* Queue
)。如果线程试图通过调用
KQUEUE
或KeRemoveQueue
(ZwRemoveIoCompletion
)从GetQueuedCompletionStatus
中删除数据包,而IOCP中没有数据包(EntryListHead
为空),那么该线程当然会进入等待状态。但是,如果存在数据包,系统将查看
CurrentCount
和MaximumCount
。如果是CurrentCount < MaximumCount
,则将删除一个数据包(并且CurrentCount++
递增)。否则,线程将进入等待状态。如果一个线程向其他线程先前正在等待的IOCP插入一个新数据包,则只有在(
CurrentCount < MaximumCount
)时,才会以LIFO顺序唤醒一个数据包。什么时候:
KeWaitForObject
)KeWaitForObject
的调用)KeDelayExecution
(Sleep)称为系统查看
Thread->Queue
,如果不是0
,则CurrentCount--
会递减。此外,如果IOCP中存在数据包,线程正在等待它,并且CurrentCount < MaximumCount
则一个线程将被唤醒。因此,逻辑实际上非常复杂,但是重点仅在于
MaximumCount
线程将能够立即处理来自IOCP的数据包。通常,最好的值是
KeNumberProcessors
,但是(在某些特殊情况下)分析工具可以帮助您确定一个更适合您情况的其他值。关于c++ - 如何在 `NumberOfConcurrentThreads`中使用参数 `CreateIoCompletionPort`,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38133870/