我有30个任务work(),有两种方案:
1.方案一:
运行一个程序,开30条线程去完成;
Thread[] threads;
for(int i=0;i<30;i++){
threads[i] = new Thread(new ThreadStart(work));threads[i] .Start();}
2方案二:
运行三个程序,每个开10条线程去完成;
Thread[] threads;
for(int i=0;i<10;i++){
threads[i] = new Thread(new ThreadStart(work));threads[i] .Start();}为什么方案二的效率比方案一要明显高,不知道原因在哪里?

解决方案 »

  1.   

    .NET下开线程很吃资源,开多了就慢
      

  2.   

    同意楼上的兄弟的说法,用 ThreadPool 吧,work() 里面的任务没有先后顺序的话,类似于 分布式计算的东东了,可以了解一下。
      

  3.   


    线程较多的时候,用ThreadPool可以节省很多开支
    尤其是10个以上线程……
      

  4.   

    我想是这样的:
    Windows按进程为单位进行执行调度,在你开一个程序30个线程时,是开了一个进程,在系统里的诸多执行进程中你的程序会得到一份时间,而这一份时间被分到30个线程中去分享
    在你开三个程序每个10线程时,是开了三个进程,总体上看你的程序会获得三份时间,每份时间被分到10个线程中去分享。
    所以开三个程序在相同的时间内获得的CPU时间要比开一个程序多,所以显得效率高些。这种说法可能不十分准确,但应该是比较容易理解的。
      

  5.   

    1. 如果 work() 是 CPU bounded,则所开的线程数不应多余内核数。如果你是双 CPU,每个 CPU 双核,则线程数不应多于 4。
    2. 如果 work() 是 IO bounded,则线程数可多些。此时应考量每个线程的 CPU 消耗,使得这组线程总体 CPU 消耗不应超过你的硬件能力。开线程是有代价的
    1. 线程切换有额外消耗,比如 10ms。具体数值依赖于具体的 CPU、操作系统、是否有 affinity 等。线程太多,切换损耗太大。
    2. 每个线程占用一个 call stack 空间。可能有 1M。建议看看 Jeffrey 的 Windows via C/C++. ThreadPool 是很好的选择,他能很智能的帮你控制线程的数量。但是,你无法控制调度优先级。而且是后台的,会被强行结束,如果应用程序想退出的话。
      

  6.   

    如果是 IO bounded,则应首先考虑 APM,而不是开线程。
      

  7.   

    threadpool无法达到你的要求 threadpool最多只能开25个线程每CPU 所以要达到你的要求 只要需要2个CPU
    13楼说的有理
      

  8.   

    30个线程算什么?? 300个我也开过,只要你的程序合理,不会卡死,不要频繁的加锁解锁和等待系统资源。.NET的线程机制是很强大的,核心效率是很高的。或者应用系统异步委托也是不错的办法。  
    但是不推荐使用太多:threads[i] = new Thread(new ThreadStart(work)); 的方法。这个方法的处理上设计线程外的很多东西。并非是线程本身效率低,而是启动线程的开销太大,启动以后就没事了。
    最好使用ThreadPool或者你自己写一个线程池。 用异步委托也不错。  至于楼主的方案一和方案二的问题确实是因为进程隔离的问题,在调度上有些差别。不过这个问题完全可以在一个程序里解决。要去调整进程和线程的优先级。
      

  9.   

    比如我们设计一个简单的计算试验用 NEW THREAD 方法和 ThreadPool.QueueUserWorkItem两种方法来试验。具体的实际计算任务是这样的( 从硬盘读一个TXT文件大小再1~50K之间 ,用正则分析文本中的地址信息,吧地址信息加到自己的集合中,完成后吧集合写到硬盘上。每个线程一次读一个,一共40个文件,线程完成后新开线程循环继续,尽量保证同时执行的线程是最大4条线)两种模式里都有一条额外主线程来监视其他线程的运行状态。双核CPU,E6400  2.0G 多次测试结果:
    1:单线模式,128~135秒完成。
    2:NEW THREAD 模式 (Max 4 T)40~47秒完成
    3:ThreadPool 模式 (Max 4 T)33~39秒完成。