如何使用asyncio ProactorEventLoop时分配线程池

问题描述 投票:0回答:1

我目前在Python 3.7中使用asyncio,并使用asyncio.start_server()函数编写一个TCP服务器请参考此示例:https://docs.python.org/3/library/asyncio-stream.html

也尝试使用“ I / O完成端口”(IOCP)的asyncio.ProactorEventLoop

根据此Microsoft官方文档https://docs.microsoft.com/en-ca/windows/win32/fileio/i-o-completion-ports,它提到将I / O完成端口与预分配的线程池一起使用,但是我找不到可以分配线程数的位置

我可以在哪里分配线程池中的线程数?有人可以在这里帮我吗?非常感谢!

python-asyncio iocp
1个回答
0
投票

有关I / O完成端口(iocp)和线程池的一般信息。我们在这里有2个选项:


全部创建:

通过CreateIoCompletionPort(或CreateIoCompletionPort)自行

create iocp

通过自行创建线程,将其称为NtCreateIoCompletion(或GetQueuedCompletionStatus)。

您需要将每个文件重新绑定到iocp,再通过GetQueuedCompletionStatusNtRemoveIoCompletionNtSetInformationFile或通过NtSetInformationFile自行绑定(此Win32 API结合了FileCompletionInformationFileCompletionInformation的功能)。


使用系统iocp]]和线程池进程启动时,

系统(ntdll.dll

)创建默认线程池(现在将其命名为TppPoolpGlobalPool)。您可以对此池进行每周控制。您无法获得它的直接指针FILE_COMPLETION_INFORMATION。存在未记录的FILE_COMPLETION_INFORMATION(用于设置此池中的最大线程数),但没有用于最小线程数。

[如果需要-您可以通过CreateIoCompletionPort函数创建其他线程池。

创建新的线程池后,您可以(但不应该!)调用NtCreateIoCompletion指定该池可以分配的最大线程数,并调用NtSetInformationFile指定该池中可用的最小线程数。] >

线程池维护一个I / O完成端口。在调用PTP_POOL中创建的iocp

-我们无权直接访问它。

所以最初在进程中存在一个全局/默认线程池(TppPoolpGlobalPool)和iocp

(并行加载程序的Windows 10创建了一个线程池LdrpThreadPool,但这当然仅供内部使用-在加载DDL时)

最后,您通过调用TpSetDefaultPoolMaxThreads将自身文件绑定到iocp

请注意,此处的msdn文档是错误的-

创建一个新的I / O完成对象。

真的CreateThreadpool函数不是

创建新的I / O完成对象-它仅在调用CreateThreadpool内部创建。此api绑定文件(不是处理文件,而是文件!)到与池关联的I / O完成对象。到哪个游泳池?寻找最后一个参数-指向SetThreadpoolThreadMaximum的可选指针。

您可以通过以下方式指定线程池-分配回调环境,先为其调用SetThreadpoolThreadMaximum,然后再调用SetThreadpoolThreadMinimum

如果不指定线程池,则将在调用SetThreadpoolThreadMinimum中使用全局线程池-因此文件将绑定到默认/全局进程iocp

并且在这种情况下,您不需要自行调用CreateThreadpool(或CreateThreadpool)-系统从池中为您执行此操作。然后调用您的CreateThreadpoolIo回调函数,您将该函数传递给CreateThreadpoolIo调用中的系统>


我们也可以通过CreateThreadpoolIo使用系统全局线程池和iocp(或CreateThreadpoolIo)-它将全局(TppPoolpGlobalPool

)线程池拥有的I / O完成端口与指定的文件句柄相关联。这是旧的api,是第2种情况的变体。在这里,我们不能使用自定义轮询-只能全局处理。

现在回到具体的Python代码。使用哪种情况?它是自己创建iocp和线程池吗?还是使用系统线程池?如果使用系统-使用它由CreateThreadpool分配的全局或自定义线程池?如果您不知道这一点-在这里什么也做不了。并且即使知道..或该库具有特殊的api /接口(或python中的此接口如何调用)也可以控制此(如果使用了self或custom pool),或者您只能按原样使用它。并且很难决定您池中真正需要多少个线程

© www.soinside.com 2019 - 2024. All rights reserved.