简体   繁体   English

C#多线程代码中的CPU使用率高

[英]High CPU usage in C# multi-threaded code

I don't have much knowledge in writing good multi-threaded code. 我没有编写好的多线程代码的知识。 I have just recently started working on a project where it is necessary. 我刚开始在需要的项目上工作。 I have written the following code, which works as I want it to, however, the CPU usage is very high. 我已经编写了以下代码,它可以按我的意愿工作,但是,CPU使用率很高。 I am assuming it is due to how I am using the threads. 我假设这是由于我如何使用线程。 If anyone could point out the flaw in the below code and let me know how to fix it so the CPU usage is not so high, I would greatly appreciate it. 如果有人指出以下代码中的缺陷并让我知道如何修复它,以使CPU使用率不高,我将不胜感激。

var numberOfMinutes = Convert.ToInt32(ConfigurationManager.AppSettings["NumberOfMinutesToRun"]);
var traversals = DbLayer.GetTraversals().ToList();
var numberOfThreads = Convert.ToInt32(ConfigurationManager.AppSettings["NumberOfThreads"]);
var threads = new List<Thread>(numberOfThreads);
var counter = 1;
var s = new Stopwatch();
s.Start();
var sync = new object();
while (s.Elapsed < TimeSpan.FromMinutes(numberOfMinutes))
{
    for (var i = 0; i < (numberOfThreads - threads.Count); i++)
    {
        var counter1 = counter; // due to closure.
        var traversal = traversals.FirstOrDefault(t => t.Id == counter1);
        var threadStart = new ThreadStart(new CallHelper(traversal).Migrate);
        var i1 = i;
        threadStart += () =>
                       {
                            threads.RemoveAt(i1);
                       };
        threads.Insert(i, new Thread(threadStart) {IsBackground = true});
        threads[i].Start();
        lock (sync)
        {
            counter++;
            if (counter > 6)
            {
                counter = 1;
            }
        }
    }
}
s.Stop();

I updated the code to show, what I hope, is required to help me. 我更新了代码,以显示希望得到的帮助。 The traversals collection contains only 6 items. 遍历集合仅包含6个项目。 The counter is there to ensure that the threads rotate through each of the 6 items in the traversals collection. 计数器在那里,以确保线程遍历遍历集合中的6个项目中的每一个。 The CallHelper class is just performing a very long running task on each traversal. CallHelper类仅在每次遍历上执行一个运行时间很长的任务。 The application is designed to perform the long running task on 6 different objects using a configurable amount of threads for a configurable amount of time. 该应用程序旨在使用可配置数量的线程在可配置的时间内对6个不同的对象执行长期运行的任务。 Hopefully I have filled in enough of the blanks. 希望我已经填补了足够的空白。

There are a variety of resources available on line for writing good and efficient multi-threaded code. 在线上有各种资源可用于编写优质高效的多线程代码。 "Good" generally refers to working and robust code. “良好”通常指有效且健壮的代码。 For efficient code, use embedded resources. 为了获得有效的代码,请使用嵌入式资源。

I only scanned your code but can see a variety of issues and can offer suggestions. 我只扫描了您的代码,但可以看到各种问题并可以提供建议。

  1. Use a thread pool. 使用线程池。 Building and tearing down threads is very expensive. 建立和拆除线程非常昂贵。
  2. Repeat the loop as infrequently as possible (as mentioned above). 尽可能不频繁地重复循环(如上所述)。
  3. Use sleeps and not busy loops when you need to delay. 需要延迟时,请使用睡眠而不是繁忙的循环。
  4. Use non-trivial code to test efficiency. 使用非平凡的代码来测试效率。 If you are testing against trivial code, your utilization will be dominated by program (not just thread) setup and tear down, something that is very expensive and will dominate the cpu utilization. 如果您要对琐碎的代码进行测试,则利用率将由程序(而不仅仅是线程)的安装和拆卸控制,这非常昂贵,并且将主导cpu的利用率。
  5. Measure the utilization of the code you are interested in and exclude that which you are not, such as application setup and tear down. 衡量您感兴趣的代码的利用率,并排除不感兴趣的代码,例如应用程序设置和拆卸。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM