为什么OmniThreadLibrary只能使用60个线程,而.NET的限制是32768个线程?

4

最近我在比较OmniThreadLibrary和.NET中的ThreadPool,发现Omni的最大线程数限制更多,只允许60个,而.NET 4.0可以达到32768个

为什么会有这样的限制呢?


1
可能还有另一个原因,那就是堆栈大小。在Delphi中,默认情况下为每个线程分配1MB的地址空间用于堆栈。在32位进程上,即使有未使用的内存,您也会遇到超出内存异常的问题,当线程计数达到1000时。这是由于32位应用程序的可用地址空间为2.1GB。 - Mike Taylor
顺便说一下,如果您使用带有IPC的多进程,则可以绕过此限制。然后您可以拥有60+个线程。 - user1647411
2个回答

8
这是一个历史性的选择,一旦可能会被取消。限制仅适用于线程池实现。
网站上有解释,如下所述:
“60个并发线程的限制仅适用于线程池。线程池旨在快速执行许多小请求,而不是作为少数活动线程的存储器。”
“您可以跳过线程池直接使用OTL任务。这样,您可以创建数百个任务。”
此限制的原因是深层次地使用了[OtlTaskControl]TOmniTaskExecutor.WaitForEvent中的MsgWaitForMultipleObjectsEx,该函数具有此限制。如果确实需要运行超过60个并发线程的任务池,则可以绕过此限制。

1
顺便说一句,链接已经失效了。OTL论坛似乎已经死了。 - David Heffernan
是的,不幸的是。有一个关于这个问题的报告(https://code.google.com/p/omnithreadlibrary/issues/detail?id=59),尽管我不知道论坛何时会恢复或是否会恢复。 - GolezTrol
我说这个限制适用于Parallel.For/Foreach函数,是吗?如果是这样的话,我们需要手动更改代码来创建任务,因为我们需要> 60个线程。在OTL中是否有一种简单的方法可以等待一组任务完成(WaitFor或类似)? - Alan Clark

1
您可以通过更改以下内容来绕过此问题:
在Winsock.pas中,将FD_SETSIZE = 1024更改为其他值。
在OtlThreadPool.pas中,将CMaxConcurrentWorkers = 1024;更改为其他值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接