【问题标题】:If a task gets locked, does it go back to the queue, or does it lock the thread too?如果任务被锁定,它会返回队列,还是也锁定线程?
【发布时间】:2020-03-02 18:23:49
【问题描述】:

我想知道在主要问题是资源锁定(例如 COM 端口访问)的情况下,任务有多好。

如果我的任务是这样的:

    Task
    {
        lock(resource)
        {
            resource.doSomething();
        }
    };

它的本质是等到资源空闲,然后使用它。

我的问题是:如果资源被锁定,任务是返回任务队列,还是线程被锁定直到资源空闲?

我的理解是,如果任务被锁定,在这种场景下,最好使用线程来避免锁定线程填充线程池,对吗?

【问题讨论】:

  • 不,它不会返回任务。其他线程被阻止获取锁(资源除外),一直等到锁被释放。
  • 你想要async lockHere 是另一个讨论。

标签: c# multithreading threadpool


【解决方案1】:

你的假设是正确的。该任务一直等到资源空闲,然后继续执行。
您可以将任务定义为LongRunning 1,这样系统处理起来更合适。此外,您可以出于任何原因运行线程,但要考虑到锁定线程不会消耗太多 CPU 资源,并且 ThreadPool 本身会处理足够数量的活动线程。如果您不打算运行很多任务(比如超过 1000 个),请不要担心。

【讨论】:

    【解决方案2】:

    System.Threading.ThreadPool 类的当前实现在饥饿时每 500 毫秒生成一个新线程。如果您以阻塞方式使用许多线程池线程,这可能会产生延迟。但是可以通过使用方法SetMinThreads 来增加ThreadPool 中线程的初始储备。每个线程消耗大约1MB 的内存,因此在这种情况下,您将用内存换取性能。

    int workerThreads, completionPortThreads; // Get the current settings
    ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
    ThreadPool.SetMinThreads(100, completionPortThreads);
    

    您可能不想更改完成端口线程池(处理 IO 请求完成的线程)的大小。所以可以通过GetMinThreads方法获取当前大小,然后在SetMinThreads中使用,保持默认即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      相关资源
      最近更新 更多