Task.Run如何受到CPU内核的限制? [英] How is Task.Run limited by CPU cores?

查看:132
本文介绍了Task.Run如何受到CPU内核的限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么下面的程序将只运行有限数量的阻止任务.限制数量似乎是计算机上的内核数量.

Why is it that the following program will only run a limited number of blocked tasks. The limiting number seems to be the number of cores on the machine.

最初,当我写这篇文章时,我希望看到以下内容:

Initially when I wrote this I expected to see the following:

  • 作业1-24的完整输出
  • 2秒间隔
  • 作业的输出25-48

但是输出是:

  • 作业1-4的完整输出
  • 然后每隔100ms随机完成一次作业.

在具有32个核心的服务器上运行时,程序确实按预期运行.

When running on server with 32 cores, the program did run as I had expected.

class Program
{
    private static object _lock = new object();
    static void Main(string[] args)
    {
        int completeJobs = 1;
        var limiter = new MyThreadLimiter();
        for (int iii = 1; iii < 100000000; iii++)
        {
            var jobId = iii;
            limiter.Schedule()
                .ContinueWith(t =>
                {
                    lock (_lock)
                    {
                        completeJobs++;
                        Console.WriteLine("Job: " + completeJobs + " scheduled");
                    }
                });
        }

        Console.ReadLine();
    }
}

class MyThreadLimiter
{
    readonly SemaphoreSlim _semaphore = new SemaphoreSlim(24);

    public async Task Schedule()
    {
        await _semaphore.WaitAsync();

        Task.Run(() => Thread.Sleep(2000))
            .ContinueWith(t => _semaphore.Release());
    }
}

但是用Task.Delay替换Thread.Sleep可以得到我期望的结果.

However replacing the Thread.Sleep with Task.Delay gives my expected results.

    public async Task Schedule()
    {
        await _semaphore.WaitAsync();

        Task.Delay(2000)
            .ContinueWith(t => _semaphore.Release());
    }

使用Thread可以得到我期望的结果

And using a Thread gives my expected results

    public async Task Schedule()
    {
        await _semaphore.WaitAsync();

        var thread = new Thread(() =>
        {
            Thread.Sleep(2000);
            _semaphore.Release();
        });
        thread.Start();
    }

Task.Run()如何工作?是否仅限于内核数?

How does Task.Run() work? Is it the case it is limited to the number of cores?

推荐答案

Task.Run安排工作在线程池中运行.线程池具有很大的自由度,可以最大程度地调度工作,以最大程度地提高吞吐量.如果认为它们会有所帮助,它将创建其他线程;如果认为无法为线程提供足够的工作,则会从池中删除线程.

Task.Run schedules the work to run in the thread pool. The thread pool is given wide latitude to schedule the work as best as it can in order to maximize throughput. It will create additional threads when it feels they will be helpful, and remove threads from the pool when it doesn't think it will be able to have enough work for them.

创建数量超出处理器能够同时运行的线程的工作在CPU受限的情况下将无法实现高效的工作.添加更多线程只会导致更多上下文切换,增加开销并降低吞吐量.

Creating more threads than your processor is able to run at the same time isn't going to be productive when you have CPU bound work. Adding more threads will just result in dramatically more context switches, increasing overhead, and reducing throughput.

这篇关于Task.Run如何受到CPU内核的限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆