我有一个程序,特别注重性能,苦于不懂C++,只好死马当活马医,用C#挖潜,据说在很多方面C#的性能不输C++。多线程C#准备的东西很多,THREAD、THREADPOOL、TASK、TPL等,还一些其它的叫法不同,但各有利弊,比如说我想用THREAD,但开销大,创建线程慢,THREADPOOL好像不太稳定,而且没有优先级,SMARTPOOL这个有名的线程组件有所耳闻,支持有优先级分组,但好像很多线程的PK大赛上,效果都不佳啊,实战怎么样呢?
    而且线程开的越多,程序性能能否越好?有人说CPU70-80左右就最好,有人说有些地方用多线程无用,我有种感觉,如果我在程序的一个方法中用了多线程,这个方法的表现很好,但总体表现,程序的整体性能却下降了,意思是说,影响了其它的方法,如何平衡负载呢,除了优先级,想不到其它的?

解决方案 »

  1.   

    就看你的线程干什么,如果你的线程大部分时间都在等待网络数据,读取文件等,那么线程可以开多一些,这样程序简单,但线程也是很耗资源的,开太多也不好,如果你的线程大部分工作都在消耗cpu,那么线程越多性能越差,此时线程数应该等于n-1,n是运行机器的cpu数目,如果线程数多于cpu数目,那么这些线程就会争抢cpu,不仅不能提高性能,切换过程还会造成额外的损耗,速度反而变慢,
      

  2.   

    多线程,主要是想提高程序的可伸缩性。例如,有很多任务需要并行进行,那么可能需要多线程。
    多线程实际上是一个假象,就是说,因为CPU的时间总是有限的,那么CPU需要频繁地切换,在某个时间执行某个线程的任务。这种情况,如果用的不好,反而增加了CPU的负担,降低了系统性能。
      

  3.   

    是你的cpu数量而定吧,只有cpu数量大于线程数量时,才可能有并行,一般线程数不要超过cpu数量2倍
      

  4.   

    对于多线程的性能,类库的选择一般都是次要的。
    主要的是把各种IO与CPU程序段分离,实现流水线模式,让瓶颈处于满负荷的状态。
      

  5.   

    感觉楼主有点过于纠结线程这个概念了,前面几位也说了,其实最终还是cpu来做这些事务,额外加入的线程切换,反而消耗更多cpu时间片。
    其实逻辑上的优美设计更有用,比如有同步需要锁定变为可异步执行。由轮询变为事件通知,效率不知道高多少。如果只是thread和threadpool的取舍。闲置线程数量增减等角度来优化,效果有限。
    举例简单例子,很多对象需要操作数据库,其实只是写入一个很小的string,如果都去开关数据库,浪费太大。可以设计一个队列,来临时保存数据。
      

  6.   

    1、线程不等于降低cpu占用率,只有在线程中加入合理的同步机制才可能提高效率,降低占用率;
    2、线程优先级高不等于性能高,只有各线程配合紧密,合理分配线程数量才能尽可能提高性能;
    3、线程池主要是为了减少内核切换开销用的,在使用数量少且切换很少情况下意义不大。
      

  7.   

    如果需要new很多线程,那么最好用线程池,否则线程池没多少意义,
      

  8.   

    那我现在每天用来测试的两台服务器来说吧,它们的配置一样,如下:2012/10/22 17:10:38开始启动系统.....企业服务XXXXX系统,XXXX 2012
    @D:\XXXXXXXXX\XXX\Server\当前服务器有40个核心
    已安装物理内存32.00G(8个插槽)
    可用物理内存31.99G,目前剩余21.29G
    可用虚拟内存8192.00G,目前剩余8191.44G
    操作系统Microsoft Windows Server 2008 R2 Enterprise (V6.1.7600.0),Win32NT平台
    可用线程数:工作线程=32766/32767, I/O完成端口线程=1000/1000
    名称为“ww”的命名管道已经启动...
    Silverlight授权服务在端口943启动。
    TCP服务已经在端口4518启动...
    HTTP服务在位置http://+:14518/启动..
    所有服务启动完毕!--------------------------------------------------------------------------------
    你的浏览器信息:
    Connection=Keep-Alive
    Accept=*/*
    Accept-Encoding=gzip, deflate
    Accept-Language=zh-cn
    Host=172.16.21.100:14518
    User-Agent=Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0E; .NET4.0C)--------------------------------------------------------------------------------
    当前有0个客户端会话。最多授权10000000个客户端会话。你说需要多少线程、什么优先级呢?其实如果你就是想写个什么小程序去“参加编程比赛”,或者就是为了应付学校毕业而弄个什么“有技术含量的”论文,这跟工程往往没有多少关系,这往往就是弄出繁琐、特例、只能限于手工作坊里有效的结论来。学生时期你“看得上”的大多数“技术”其在实际工程中都会被推翻。
      

  9.   

    在我的工作中,需要自己编写服务器程序,以及silverlight等企业客户端程序。不论是服务器端还是客户端,都特别大量地使用多线程编程。可是如果纠结你的这个问题,我想我就没法正常工作了,只能靠上学或者靠参加编程大赛为生了。
      

  10.   

    而我在家里用来测试的一台破电脑(我自己花1500块钱攒的,一个200多块钱的最低档奔腾双核cpu)2012/10/23 4:19:55开始启动系统.....企业XXXXX系统,XXXX 2012
    @C:\Users\XXXXXX\Desktop\XXXXXX\TestMaster\bin\Debug\当前服务器只有2个核心,系统建议升级到6核心服务器!
    已安装物理内存4.00G(1个插槽)
    可用物理内存3.72G,目前剩余2.03G
    可用虚拟内存8192.00G,目前剩余8191.37G
    操作系统Microsoft Windows 8 企业版(V6.2.9200.0),Win32NT平台
    可用线程数:工作线程=32766/32767, I/O完成端口线程=1000/1000
    名称为“ww”的命名管道已经启动...
    TCP服务已经在端口4518启动...
    Silverlight授权服务在端口943启动。
    HTTP服务在位置http://+:14518/启动..
    所有服务启动完毕!--------------------------------------------------------------------------------
    你的浏览器信息:
    DNT=1
    Connection=Keep-Alive
    Accept=text/html, application/xhtml+xml, */*
    Accept-Encoding=gzip, deflate
    Accept-Language=zh-CN
    Host=localhost:14518
    User-Agent=Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)--------------------------------------------------------------------------------
    当前有0个客户端会话。最多授权1000000个客户端会话。不论是在那一个平台上,我都运行同一个程序,因为确实没有闲工夫去担心这个担心那个地。实际上主要的“技术”都出自实际去测试,这样才能解决稍显复杂的工程问题,而不是简单地来自于“抠字眼的”基本概念。
      

  11.   

    TO:sp1234,我都没明白你说的什么,也不明白你的例子是何意,而且我的不是服务器程序,是桌面应用程序。