比如一个线程执行完了一个任务后自然终止,或者我调用abort方法让它终止后,它的IsAlive已经变为false后,能否再次运行同样的任务呢?也就是能否再次被Restart呢?
我不太想new一个新线程,既然这个线程已经闲下来了,应该可以再用的吧?
.Net 中表示线程的类 Thread 一旦终止,它就无法通过再次调用 Start 来重新启动。.Net Thread 终止,“闲下来”的不是 .Net Thread,而是 Windows Thread Pool 中的线程。建议你阅读以下章节:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686756(v=vs.85).aspx
已创建的线程会关联到 I/O completion 队列,当一个线程执行完自己的任务后,会被设置为 alertable wait 状态,此时已为线程分配的数据结构会被保留,当有请求被投递到 I/O completion 队列后,系统会通过一定的算法找出一个合适的处于 alertable wait 状态的线程,并将任务委派给它。
我不知道你们公司的程序是具有什么特性,但是要提高性能,简单来说,你需要区分I/O和非I/O(CPU密集型)操作。对于I/O操作,在 .Net 中应该使用类的 BeginXXX (比如:FileStream.BeginRead)形式的 API 来调用;对于非 I/O 操作,应该尽可能将任务细化,然后通过并行的方式执行(使用 Thead Pool或使用 PPL,TPL)。
当然,除了Thread Pool采用的抢先式计划模型,你也可以采用协作式计划模型,比如 Microsoft CCR and DSS(.Net)、Concurrency Runtime(C++)。
我的回答都只是蜻蜓点水,只是简单的提供一些资料,并不能直接解决你的问题。
完全可以,只要对象没被销毁就不需要重新来过,不过如果线程数目动态改变的话用线程池不错
关键是怎么弄啊,哪个方法呀?
@沧海一杰: http://www.cnblogs.com/wildman/archive/2008/08/22/1274170.html#commentform
看了就知道怎么弄了,.net环境下很简单。
至于单个线程暂停重启可以用这个http://blog.sina.com.cn/s/blog_49c211fa010190a4.html
@大芝麻: 线程池有诸多限制,而且我的项目用线程池会显得更复杂,所以暂时用手动控制。
一般情况下应该用线程池(BackgroundWorker.DoWork, ThreadPool.QueueUserWorkItem 或 Task.Run),不应该自己 new Thread.
@大芝麻: 这是你说的,微软可没这么说过,要不它就不用提供new方法了。
@沧海一杰: 这是Jeffrey Richter 在 CLR via C# 中说的,不是我说的。
@deerchao: ThreadPool.QueueUserWorkItem有线程调度。但是好像不支持前台线程
这个问题你写两行代码一试就清楚了。
即使假设线程可以被重启,但实际上它已经被中止了(自然终止后手动abort),就目前的.Net线程实现来看,其底层的OS线程已经结束了, 即使重启也只能是再重开一个OS线程, 而你却担心那个new操作的开销 -- new一个线程实例的开销比起真正 start 一个线程简直可以无视。
是这样啊
@沧海一杰: 关于线程池里的线程,当你指定的代码执行完之后, 线程并不退出,而是进入等待状态。 你可以通过各种 WaitHandle 来模拟这个东西, 比如 event.WaitOne(),然后当想再用时就 event.Set()。 但理论上线程这样做与线程池相比并不会有性能上的提升。 线程只要启动了最好是持续的干活, 好比养头牛却总让它睡觉没活干,白白浪费草料。
.NET本身提供线程池功能,就是为了线程的重用的。建议直接使用.NET的线程池。
我们公司大量线程一般都不建议使用线程池,因为有性能问题。
@沧海一杰: 用线程池无法达到我需要的性能指标。
@沧海一杰: 我不知道你说的性能问题是什么,我认为是你们的用法不对。线程重用本身就应该使用线程池来实现,而.NET的自带实现显然要比你自己写一个线程池性能高。
谢谢大家,听了大家说的我对线程有了新的认识;对于线程池用得比较少,性能问题也只是前人所讲,并未在实际项目中真正测试过。