需要帮助理解 .net ThreadPool

发布于 2024-10-18 14:42:23 字数 937 浏览 6 评论 0原文

我试图了解 ThreadPool 的作用,我有这个 .NET 示例:

class Program
{
    static void Main()
    {
        int c = 2;

        // Use AutoResetEvent for thread management

        AutoResetEvent[] arr = new AutoResetEvent[50];

        for (int i = 0; i < arr.Length; ++i)
        {
            arr[i] = new AutoResetEvent(false);
        }

        // Set the number of minimum threads
        ThreadPool.SetMinThreads(c, 4);

        // Enqueue 50 work items that run the code in this delegate function
        for (int i = 0; i < arr.Length; i++)
        {
            ThreadPool.QueueUserWorkItem(delegate(object o)
            {
                Thread.Sleep(100);
                arr[(int)o].Set(); // Signals completion

            }, i);
        }

        // Wait for all tasks to complete
        WaitHandle.WaitAll(arr);
    }
}

这会以 2 个一组 (int c) 的形式运行 50 个“任务”,直到它们全部完成吗?或者我不明白它的真正作用。

I am trying to understand what ThreadPool does, I have this .NET example:

class Program
{
    static void Main()
    {
        int c = 2;

        // Use AutoResetEvent for thread management

        AutoResetEvent[] arr = new AutoResetEvent[50];

        for (int i = 0; i < arr.Length; ++i)
        {
            arr[i] = new AutoResetEvent(false);
        }

        // Set the number of minimum threads
        ThreadPool.SetMinThreads(c, 4);

        // Enqueue 50 work items that run the code in this delegate function
        for (int i = 0; i < arr.Length; i++)
        {
            ThreadPool.QueueUserWorkItem(delegate(object o)
            {
                Thread.Sleep(100);
                arr[(int)o].Set(); // Signals completion

            }, i);
        }

        // Wait for all tasks to complete
        WaitHandle.WaitAll(arr);
    }
}

Does this run 50 "tasks", in groups of 2 (int c) until they all finish? Or I am not understanding what it really does.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦回旧景 2024-10-25 14:42:23

如果您有时间,我真的建议您阅读以下内容:

http://www.albahari.com /threading/

这是一本出色的读物,它奠定了从基本线程到并行编程的基础和工作方式。我建议您在尝试修改线程池代码之前先基本掌握前两章! :)

If you've got a bit of time, I would really recommend this read:

http://www.albahari.com/threading/

It's an excellent read that lays the foundation and works it's way from basic threading to parallel programming. I'd recommend you to have a basic grasp of the first two chapters before trying to modify threadpool code! :)

野生奥特曼 2024-10-25 14:42:23

通过设置最小线程数,您要求 .NET 运行时做的唯一一件事就是为线程池分配至少 2 个线程。您并不是要求它将自身限制为 2 个。

因此,无法保证您的程序将使用多少个线程。这取决于您的系统和许多其他因素。

我做了一个简单的测试(对程序进行了微小的更改,以跟踪进入 sleep 调用的同时线程),一次运行最大为 4 个,另一次运行为 3 个,另一个运行为 7 个,另一个运行为 10 个,等等。

你真的不应该需要更改线程池大小。

你想实现什么目标?

By setting the minimum number of threads, the only thing you're asking the .NET runtime to do is to please allocate at least 2 threads for the thread pool. You're not asking it to limit itself to only 2.

As such, there is no guarantee on how many threads in particular your program will use for this. It depends on your system and a lot of other factors.

A simple test I made (minor change to your program to just keep track of simultaneous threads entering the sleep call) maxed out at 4 in one run, 3 in another, 7 in another, 10 in another, etc.

You really shouldn't need to change the thread pool size.

What are you trying to accomplish?

廻憶裏菂餘溫 2024-10-25 14:42:23

来自 SetMinThreads 的 MSDN 文档:

当需求较低时,实际数量
线程池线程数可能会低于
最小值。

因此,您指定的值并不能保证 2 个工作线程将处理排队的项目。它可能是 1 个工作线程(因为您在循环中对它们进行排队,因此它可能会在下一个工作线程排队之前完成),或者它可以根据系统资源和必须完成的工作量使用更多工作线程。

如果您确实想了解发生了什么,请查看 Process Monitor。您可以监视进程的线程创建并跟踪它们何时创建、销毁等。这将真正帮助您了解应用程序(和底层框架)正在做什么。

希望这有帮助。

From the MSDN documentation on SetMinThreads:

When demand is low, the actual number
of thread pool threads can fall below
the minimum values.

So the value that you specify doesn't guarantee that 2 worker threads will work on the queued items. It could be 1 worker thread (since you're queueing them up in a loop, it may finish before the next one gets queued up), or it could use more based upon the system resources and the amount of work that has to be done.

If you really want to see what's going on, check out a tool like Process Monitor. You can monitor your process' thread creation and track when they're created, destroyed, etc. It will really help you realize what your application (and the underlying framework) is doing.

Hope this helps.

优雅的叶子 2024-10-25 14:42:23

背景:.NET 线程池管理线程的常规方法可能很麻烦。它可以很好地限制由资源争用引起的问题,但这样做是以牺牲线程创建速度为代价的。为了提高线程池中工作线程的性能,设计者允许使用一种机制,允许在不经过队列过程的情况下创建一定数量的线程。

SetMinThreads() 指定应简单地“按需”创建的线程数,即简单地启动,而不检查当前线程计数或排队以缓慢节流。

将会发生的情况是,框架将立即创建前两个线程,就像您手动设置它们并使用 Thread.Start 启动它们一样。除此之外,直到当前的MaxThreads计数,框架将开始对工作线程的请求进行排队,并以指定的时间间隔(默认为250ms,我相信这也可以配置)启动它们,以避免资源冲突。这样做的原因是,如果您想象启动一个访问资源的线程,进行一些计算,然后将结果写入其他地方的循环行为,您可以看到 5 个线程几乎同时启动将如何导致尝试获取资源时发生僵局到第一个资源。在 MaxThreads 阈值处,队列停止;在完成之前不会创建新线程。

因此,根据代码的性质,将安排 50 个单独的工作任务,但并非所有 50 个任务都会同时运行;运行时将允许两个立即启动,然后等待 250 毫秒或直到一个结束,然后再开始下一个。由于线程将在 250 毫秒内执行并终止,因此您不太可能看到同时执行 2 个以上的工作线程;创建第三个线程之前的等待永远不会发生,因为“不受限制”的工作线程将首先释放,并且正在等待的线程在其等待时间到期之前被启动,然后时钟将与下一个线程一起重置。

Background: The normal method by which the .NET thread pool manages threads can be cumbersome. It works well to limit problems caused by resource contention, but it does so at the expense of how quickly threads are created. To increase the performance of worker threading with the thread pool, the designers allowed for a mechanism that allows a certain small number of threads to be created without going through the queue process.

SetMinThreads() specifies the number of threads that should simply be created "on demand", that is, simply started up without any checks on the current thread count or queueing to throttle up slowly.

What will happen is that the framework will create the first two threads immediately, as if you'd manually set 'em up and kicked 'em off with Thread.Start. Beyond that, up to the current MaxThreads count, the framework will begin to queue up requests for worker threads and start them at a specified interval (by default, 250ms, I believe this can also be configured) to avoid resource collision. The reason for this is that if you imagine a looped behavior of starting a thread that accesses a resource, does some calculation, then writes the result somewhere else, you can see how 5 threads starting up near-simultaneously would cause a logjam attempting to get to that first resource. At the MaxThreads threshold, the queue is stopped; no new threads are created until one finishes.

So, just by nature of your code, 50 separate worker tasks will be scheduled, but not all 50 will be running at the same time; the runtime will allow two to start immediately, then wait 250ms or until one ends before kicking off the next. Because the threads will execute and terminate in less than 250ms, you're unlikely to see more than 2 worker threads executing at once; the wait before creating that third one will never occur because an "unrestricted" worker thread will free up first and the one that was waiting is kicked off before its wait time expires, then the clock is reset with the next one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文