Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 参数'NumberOfConcurrentThreads'在'CreateIoCompletionPort'中的使用方式`_C++_C_Windows_Multithreading_Winapi - Fatal编程技术网

C++ 参数'NumberOfConcurrentThreads'在'CreateIoCompletionPort'中的使用方式`

C++ 参数'NumberOfConcurrentThreads'在'CreateIoCompletionPort'中的使用方式`,c++,c,windows,multithreading,winapi,C++,C,Windows,Multithreading,Winapi,查看forCreateIoCompletionPort我们读到: ConcurrentThreads的数量[英寸] 操作系统允许并发处理I/O完成端口的I/O完成数据包的最大线程数。如果ExistingCompletionPort参数不为NULL,则忽略此参数 如果此参数为零,则系统允许的并发运行线程数量与系统中的处理器数量相同 但是,我找到的文档没有指出IoCompletionPort实际上创建了任何线程 // The general value of the thread count is

查看for
CreateIoCompletionPort
我们读到:

ConcurrentThreads的数量[英寸]

操作系统允许并发处理I/O完成端口的I/O完成数据包的最大线程数。如果ExistingCompletionPort参数不为NULL,则忽略此参数

如果此参数为零,则系统允许的并发运行线程数量与系统中的处理器数量相同

但是,我找到的文档没有指出
IoCompletionPort
实际上创建了任何线程

// 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);
}
事实上,Microsoft提供的应用程序使用以下代码来确定有多少处理内核可用(而不是将
0
传入
numberofconcurrenthreads
),然后实际创建那么多线程

// 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);
}
//线程计数的一般值是系统的处理器计数。
系统信息sysInfo={0};
GetNativeSystemInfo(&sysInfo);
常量DWORD dwThreadCount=sysInfo.dwNumberOfProcessors;
//示例中围绕IoCompletionPort的类
IOCompletionPort端口;
//构建线程池
HANDLE*hThreads=新句柄[dwThreadCount];
对于(DWORD i=0;i
在我看来,这似乎表明某种程度上存在与
IoCompletionPort
相关联的“承载能力”。但这是如何体现的呢?我很难理解一个能够访问完成端口的线程如何(甚至为什么需要这样做)防止从完成端口退出队列

事实上,我尝试将创建线程的行修改为
newhandle[++dwThreadCount]
(并从声明中删除
const
说明符),该示例似乎可以毫无怨言地执行。我只是在执行结束时注意到一个额外的超时错误


我目前唯一的结论是,
NumberOfConcurrentThreads
是一个没有实际用途的“虚拟”变量,那么我缺少什么呢?

I/O完成端口本身不会创建线程。
NumberOfConcurrentThreads
参数指定允许多少线程同时并行处理完成数据包。另一个MSDN页面将对此进行更详细的解释:

I/O完成端口如何工作

尽管任意数量的线程都可以为指定的I/O完成端口调用
GetQueuedCompletionStatus
,但当指定的线程第一次调用
GetQueuedCompletionStatus
时,它将与指定的I/O完成端口相关联,直到发生以下三种情况之一:线程退出,指定不同的I/O完成端口,或关闭I/O完成端口。换句话说,单个线程最多可以与一个I/O完成端口关联

当一个完成数据包排队到一个I/O完成端口时,系统首先检查与该端口相关联的有多少线程正在运行如果运行的线程数小于并发值(将在下一节中讨论),则允许一个等待的线程(最近的一个)处理完成数据包。当一个正在运行的线程完成其处理时,它通常会再次调用
GetQueuedCompletionStatus
,此时它要么返回下一个完成数据包,要么等待队列为空

线程和并发性

一个I/O完成端口要考虑的最重要的属性是并发值。strong>使用

CreateIoCompletionPort
通过
NumberOfConcurrentThreads
参数创建完成端口时,指定完成端口的并发值。此值限制与完成端口关联的可运行线程的数量。当与完成端口关联的可运行线程总数达到并发值时,系统将阻止与该完成端口关联的任何后续线程的执行,直到可运行线程数降至并发值以下

最有效的情况发生在队列中有完成数据包等待,但由于端口已达到其并发限制,无法满足任何等待。考虑一个和多个线程在<代码> GeQueIDFultEntOntys/Cuff>函数调用中等待的并发值会发生什么。在这种情况下,如果队列始终有完成数据包等待,则当运行的线程调用
GetQueuedCompletionStatus
时,它不会阻止执行,因为如前所述,线程队列是LIFO。相反,此线程将立即拾取下一个排队完成数据包。不会发生线程上下文切换,因为正在运行的线程正在不断拾取完成数据包,而其他线程无法运行

为并发值选择的最佳总体最大值是计算机上的CPU数量。如果事务需要长时间的计算,则较大的并发值将允许更多线程运行。每个完成数据包可能需要更长的时间才能完成,但会同时处理更多的完成数据包。您可以将并发性值与分析工具结合使用,以实现应用程序的最佳效果

如果与同一I/O完成端口关联的另一个正在运行的线程由于其他原因(例如
SuspendThread
函数)进入等待状态,系统还允许在
GetQueuedCompletionStatus
中等待的线程处理完成数据包