繁体   English   中英

有没有更好的方法来实现多线程?

[英]Is there a better way to implement multithreading?

下面的源代码部分使CPU消耗很高! 有没有更好的方法来实现多线程?

// This application will run 24 hours 7 days per week
//     in server

static void Main(string[] args)
{
    const int NUM = 10;

    Thread[] t = new Thread[NUM];

    for (int i = 0; i < t.Length; i++)
        t[i] = new Thread(new ThreadStart(DoWork));

    foreach (Thread u in t)
        u.Start();
}

static void DoWork()
{
    while (true)
    {
        // Perform scanning work
        // If some conditions are satisfied,
        //     it will perform some actions
    }
}

如果不清楚while(true)旋转循环中的内容,则很难回答这个问题。 如果您启动10个线程而每个线程都没有任何等待就旋转(使用AutoResetEvent.WaitOne()Thread.Sleep()等),则CPU将被消耗-因为您要向CPU请求。

为了提高整体性能,如果不是绝对必要的,则线程不应该旋转-在大多数情况下不是这样。 线程应完成其工作,然后如果没有更多工作要做,则应入睡。 仅当它们有更多工作项目要处理时,才应将它们唤醒。 如果您的线程一直在运行-检查不时满足的某些条件, 并且您有一种机制可以通知线程该条件为真 -那么旋转就浪费了CPU周期。

从概念上讲,线程应以这种方式工作。

while(true)
{
    // Wait until a thread has something meaningful to do. Waiting can be done for instance by calling AutoResetEvent.WaitOne().

    // Do a meaningful work here.
}

如果以这种方式执行线程代码,则当线程正在等待时,它不会占用CPU,因此系统不会过度工作,其他线程/进程也可以完成其工作。

这里的主要问题是,如果您具有某种通知机制,当新工作项到达时,该通知机制允许线程唤醒。 例如,大多数IO操作(例如TCP套接字,HTTP通信,从文件读取等)都支持异步通信,该异步通信允许线程仅在收到新数据时进入睡眠和唤醒状态。

另一方面,如果您没有这样的机制-例如,您正在使用一个第三方库,该库在发生有意义的事情时不会通知您,则您必须进行某种旋转。 但是即使是这种情况,问题仍然是,您需要多久检查一次是否满足条件-因此需要做一些工作。

如果可以说,您仅需每秒检查是否满足条件,则将Thread.Sleep(1000)调用添加到线程代码中。 这将大大提高总体性能。 甚至Thread.Sleep(0)等待旋转好得多。

这里有一个重要的注意事项。 在现代C#中,不应将线程用作您的主要异步编程机制。 使用class Task使用基于任务的异步编程更容易实现,尤其是在使用await-async C#关键字的情况下,并且在大多数情况下会导致更好的性能。

如果有太多的工作项无法使用当前数量的线程处理,则任务会在内部使用线程创建新线程,如果没有足够的工作要做,则释放线程。 最佳线程数减少了总内存消耗。

如今,几乎所有标准.NET API都支持基于任务的异步编程,因此如何实现代码的并行执行应该成为您的主要工具。

是基于任务的异步编程的一些示例。

暂无
暂无

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

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