[英]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.