讨论一下多线程.200分其实也太少,不过这是我能给的最高分了.
这个贴开始在C++那边论坛发过,但没几个讨论的,不知道是不是我描述太烂了.
对于这个问题我一直是很有兴趣的(因为工作也是服务器上的应用,我较少做界面,用户交互应用),但是到现在我也没有找到很好的书来看.都是凭借自己的经验.
现在再在我们C#区发一下,我们这区够热度了.
讨论的命题:
程序把CPU拖到90%左右是否就是达到了完美效率
讨论这个前提肯定是排除垃圾消耗的代码,比如频繁启动新线程做无谓的运算。或无意义的消耗CPU时间。
只指有效代码。
比如操作一个int[] 有1000万个元素。读出来,然后做 1 个耗时1秒的操作(我们就把这个操作想成是数据库操作或者是socket send操作;每个元素耗时1秒)。如果不做多线程操作,显然我们就得消耗 1000万秒。这个时候运行这个单线程程
序CPU的消耗可能3%不到。但基本你的任务已经无法完成。
那么这样:我可以启动 10个线程,各自分配给他们各自要操作的索引段 如:0-100万,100万-200万。。。 等等这样int[]虽然是全局变量,但不用锁他。 然后10个线程各自工作。 这还是需要100万秒。
int[] 1000万数据 这个东西本身读取肯定是不需要消耗太多CPU的。 消耗时间的是后面的 操作。 而这个操作可能又有干耗以及实耗(抱歉,我就按这样形容了,干耗是指阻塞,不干活等待数据响应等等,而实耗指的是确切需要消耗CPU的动作。我后面也会以这样的认知去描述下面的问题)如果是实耗的话,我们没有办法避免。如果是单核心CPU你起10个线程和起1个线程都需要消耗X时间。而10个线程可能需要消耗更多时间,可能是X+Y 不过Y值很微小罢了。所以,我们多线程就是为了化干耗为0。所以理论上如果你达到化干耗为0,并且你这个程序持续工作X秒的话。 那么这X秒内CPU的占用率应该就会达到90%以上.
如果按我以上描述的去理解.那么下面这2个观点就是错误的.
比如:线程并非越多越好. -- 这个显然错误(或者说他是不分青红皂白的,不讲前提条件的).因为只要CPU还存在干耗的话,那么再创建1个线程肯定是更优化的选择(当然,也会有其他类似非阻塞而不加线程的更优选择)这个是非常显而易见的.比如现在你10个线程在操作 1000万数据. 每个线程要消耗1秒.而这1秒里有500毫秒是在阻塞.那么你启动10个线程显然是为了在你某些线程阻塞500毫秒的时候还有其他线程在继续工作.
但是!显然你并不能保证0干耗.这个时候如果10个线程的运算间隙都有 阻塞在干耗的话,能够显著提升效率的其中1个方案就是:再启动一个线程.
线程开启数量应该是CPU核心数+1 比如双核CPU就 可以开3个线程可以达到最高效率.这个显然是不完整的描述.(也就是错误的). 因为 如果你的程序干耗多的话,那么显然就和是否多核无关. 如果是实耗可能双核CPU开3个线程可以达到最高效率
关于线程数=CPU核心数+1 这个问题,我想大部分中级程序员都会对这个东西发窘,我开始也是不明所以,不知道这是讲的什么,只感觉这个东西在混淆视听.
而实际上,这个也很简单:也就是干耗为0的情况下(近似于0)如果你的CPU是多核的.那么请你不要再用单线程进行工作,而应该采取CPU核心数+1 的方案.
-------------------------------------
还谈谈c#的线程池与java的线程池.(这2个语言的线程池应该是近似用途与逻辑吧)
我对这个东西接触都不多,但从目测效率上感觉:这个东西的确没什么大的用处.在你需要高效运行的程序的时候最好是不要去用语言级别的线程池,因为总是感觉这个东西不是为了提高效率而设置的.具体是为什么场景设计的我也不知道(知道的可以说一说).反正提高效率尽量自己new线程,然后统一自己管理.
总结一下,多线程按本质来讲,我认为就是降低干耗,充分利用阻塞时间做其他事情.而从实际应用来讲可能有时候是:错开系统瓶颈,比如一个程序有数据库操作的话不要写成1串串下来的程序,而应该在写数据库操作的时候把线程分割开.
而多线程用到现在其实最麻烦也最难的是共享数据的线程安全.以及同步/效率的问题.
这贴用来讨论,欢迎拍砖,免得我一直脑袋里装错误看法
最后,第1次发200分的贴,不知不觉可以发200分的贴了,庆祝一下.
[解决办法]
同喜 同喜 ,多线程是编程最高境界
[解决办法]
多线程。。多核
[解决办法]
仔细看了下,我感觉楼主理解得挺深的,真是受教了,有关这方面的知识,我一直是半知半解的,现在总算有个眉目了
[解决办法]
学习来的...
[解决办法]
多线程,一直不怎么会用,用一次就出一次问题啊。
[解决办法]
你对线程的理解存在一些问题:
对于单CPU的机器来说,多线程对于大量数据的运算毫无益处,反而在线程调度上浪费时间,比如你这一段:
比如操作一个int[] 有1000万个元素。读出来,然后做 1 个耗时1秒的操作(我们就把这个操作想成是数据库操作或者是socket send操作;每个元素耗时1秒)。如果不做多线程操作,显然我们就得消耗 1000万秒。这个时候运行这个单线程程
序CPU的消耗可能3%不到。但基本你的任务已经无法完成。
那么这样:我可以启动 10个线程,各自分配给他们各自要操作的索引段 如:0-100万,100万-200万。。。 等等这样int[]虽然是全局变量,但不用锁他。 然后10个线程各自工作。 这还是需要100万秒。
对于单CPU机器来说,这是不可能发生的,微观时间内,每个时刻只能一个线程在运行。
即使对于多CPU机器来说,使用多线程能提高效率,也远不会是你描述的这样:10个线程同时工作,你有几个CPU或几个核心?
[解决办法]
单CPU机器,多线程运用在不同性质的若干工作上,比如一个读数据库,一个网络收发,一个界面更新,这是合理的,同一性质的工作,尤其是可能会阻塞的工作,多线程经常被滥用。
[解决办法]
说实话我多线程 懂的不多,仅仅是对上传限制,一般我在工作期间每个进程分割5线程 进行流量限制。
先占位,晚上来发表意见。
[解决办法]
初级程序员路过,不懂!
[解决办法]
学习的,有分得不?
[解决办法]
线程并非越多越好,这是正确的,不管你是否运用多线程,大多数情况下,CPU仍然是空闲的时间居多,因为程序需要处理其他事情而非进行数据运算。
线程数=CPU核心数+1,这个倒是未必,看线程如何运用了。
------解决方案--------------------
程序把CPU拖到90%左右是否就是达到了完美效率
----------------------------------------
这个不好说: 严格的说系统的多线程目的是节约 存储器的使用率,把一部分压力 转换到cup 那里去,
也就是所谓的压榨cup。但是做activeX开发时 又冲突了。
[解决办法]
即使是网络收发,过多的线程同样是滥用,网络收发的时候为什么会阻塞,2个线程进行网络收发与10个线程进行网络收发,你认为阻塞时间会减少吗?一群人挤在一个狭窄的过道中,我看你如何并发?
[解决办法]
6楼说的非常正确,多线程不是这样用的。如果你仅仅是为了抢占cpu,那么将进程优先级提高就好了。(当然,从某些角度来说,提高优先级也只是饮鸩止渴。)
多线程可以提高效率只是在于一些不占用cpu的I/O操作,例如等待网络的数据包返回,等待串口的数据发送完毕,等待磁盘写入完成,等等之类。
类似于我们平时说的,利用工作调度提高整体工作效率。
[解决办法]
这个问题的话.
呵呵 我说100个线程 是有点过火了. 但我是举了个例子,不太恰当.
-----------------------------------------------
我是否可以认为,你还是承认了,线程不是越多越好?
而且,如果是做同一性质的工作,线程数目的确不应该超过CPU核心数+1,拿这个例子来说,不论瓶颈在CPU还是在网络接口,更多线程都是无意义的,如果是没有瓶颈的理想状态,那么CPU也已经达到或接近满负荷了。
再说一点,线程调度的代价远比你想象的要大,因为这涉及到核心态和用户态的切换。
[解决办法]
什么时候用多线程??
1.用户界面需要.
2.性能瓶颈不在cup的时候,就可以用多线程. 特别涉及到网络发送接收.
我曾经用20~40个线程下载网站数据,整个程序就像一个下载器一样.只用一个线程来处理下载下来的数据.cpu也才最多70%.我用的还是 p4 单核的.但是网络就撑的满满的. 没办法客户说一定要快.现在做到不怕你电脑有多慢就怕你网络不够快.
有人说我用那多多线程浪费cpu资源.我说那也没办法.为了实现客户的要求的快.我必须牺牲以一点cpu资源来挤爆客户的网络.呵呵.
看应用来决定是否选择多线程.
[解决办法]
如果没有界面,如果仅仅是后台处理数据,如果在处理数据的时候,没有其它的用户在等待,如果你有足句的耐心等待数据完成,那么请不要使用多线程,原因楼上都讲了;
如果你的是多核,如果你的是分布式的系统,如果你对线程同步及互斥理解了,如果你不能使UI线程阻塞,那么可以考虑使用多线程,但在多核上使用多线程并不一定能提效率,相反效率有可能降低;
[解决办法]
服务器的确是需要多线程,即使是仅仅做后台处理,不如此无法支持并发处理的。
[解决办法]
论坛自动发贴(回复)打工机2.0 这个好多分啊 哭
[解决办法]
学习学习学习。
[解决办法]
秒级别的话确实开不了太多。本身顺序执行需要10W秒能优化到1000秒就已经是极限了吧。100线程的话还不能都用同步方法,最好是做异步调用你要处理的事务然后等回调。这样线程池资源才能好点。我觉得你优化的关键不在你的事务数,最主要是在你业务执行期间做优化。
[解决办法]
哦。补充一下,你后面的数据服务器也要够坚挺,否则撑不住。。
[解决办法]
多线程,主要是想提高程序的可伸缩性。例如,有很多任务需要并行进行,那么可能需要多线程。
多线程实际上是一个假象,就是说,因为CPU的时间总是有限的,那么CPU需要频繁地切换,在某个时间执行某个线程的任务。这种情况,如果用的不好,反而增加了CPU的负担,降低了系统性能
VS2010中提供了多CPU操作
Task Parallel Library(TPL)和Coordination Data Structures
[解决办法]
占个位,学习~~~
[解决办法]
多线程编程,并行编程
个人感觉需要分具体应用,
有位朋友说的,2个方面目标,1是友好,2是效率。
[解决办法]
CPU虽然是一个,但是使用多线程可以非常好的安排线程的优先级,把任务分为轻重缓急分别对待。占时少且重要的就给一个高优先级,这样可以随时打断低优先级的任务,它用完了CPU又可以立即返回给低优先级的任务使用。我原来编写视频播放程序时,把音频的解压和音视频的同步各用一个线程,优先级高。视频解压程序用一个低优先级的线程,他最耗时,时间来不及就不显示某些帧。但是声音断续问题更严重。
[解决办法]
感受很深
[解决办法]
我感觉多线程之妙,不在于原理,而在于动手实践
dotnet多线程,初学者一般推荐使用:backgroudwork,效率相当不错,特别是继承它之后,使用reportprogress来与线程内部属性交互,可以直接操作UI,确实又傻瓜又简单,然后自己用list做个简单的线程池,外加线程的暂停,线程退出等功能,完全可以用在多线程下载之类的软件上。。。
[解决办法]
网狐棋牌 6.6版 源码 完美源码 最新版 破解版 内核源码 免费版 ...
------解决方案--------------------
我来学习的,高手真多 ...
[解决办法]
马克了认真看
[解决办法]
偶也来学习。。
[解决办法]
做个记号明天再来
[解决办法]
Mark 学习一下~~
[解决办法]
看的云里雾里,都是N人,看看有益无害。
[解决办法]
难怪C++论坛没几个讨论的...不是你描述太烂,是你理解根本不正确...
使用多线程是为了避免线程阻塞,提高可响应性,改善交互...而不是为了提高CPU效率,事实上提高不了,总计算时间只会多不会少...某些应用的效率提升只是让系统多加班的表面现象...
滥用多线程只会降低效率,并可能带来死锁问题...这点芥子讲得够清楚了...“线程并非越多越好”是非常正确的说法...
我感觉你的问题源于没有弄明白抢占式多任务操作系统的本质,把多CPU/多核并行处理和多线程混为一谈...
你得先明白...多CPU/多核并行处理是硬件级的功能,而多线程仅仅是逻辑级的功能...就好像一个工厂,增加生产线并配置适当数量的工人才能提升生产效率,只是不断增加工人生产效率反而会越来越低...
[解决办法]
学无止境,线程很好》》》
[解决办法]
学习来了。。
[解决办法]
我感觉楼主理解得很深的,在下受益受益匪浅
[解决办法]
据个人的了解,“线程数并非越多越好”这句话是绝对正确的,增加线程数,当然是为了减少数据等待,这里的数据等待有两种,一种是闲等,一种是忙等,闲等就是某个CPU再等其他CPU释放资源或者等待用户输入数据或命令等,这个时候闲等的CPU瞬间占用率是0的。而忙等就是在占用CPU资源的情况下等待数据,例如CPU等待内存子系统返回数据。但这个时候CPU不能接受其他任务,CPU的瞬间占用率是100的。
增加CPU数和线程数可以有效地降低CPU的平均等待时间(平均每个CPU的闲等和忙等的时间总和)。但是对于单个CPU来说,例如在一台单核心单CPU的计算机上,CPU在处理一个线程结束切换到另一个线程,或者一个线程被中止切换到另外一个线程之间,是有一个线程切换的过程,当然线程切换是需要消耗CPU性能的,至于切换的算法,消耗多少CPU性能就看操作系统了。在多线程并行的操作系统中,操作系统会让每个线程进入CPU一小段时间(这段时间叫时间片)。对于当今流行的操作系统(Windows 或 Linux),当系统中需要CPU处理的线程数不断增加,操作系统会相应地缩短每个线程的时间片。换言之,就是在相同时间内系统进行线程切换的次数就多了。这样CPU的效率就显然降低了,几时对于多核心多CPU的计算机也如此。
而至于完成一个任务到底开多少线程才是最高效,我觉得要看算法中需要等待的时间和等待的类型,还有多线程之间的关联度。LZ所具体的int[] 1000万个数据,加入对于这1000万个数据的运算之间是存在关联的,例如int[2]的运算需要等待int[1]的结果,这样的话,当然吧int[1]和int[2]放到同一个线程中比较好了,虽然表面上看CPU的利用率(占用率)低了,但这样也许比int[1]int[2]分开两个线程独立运算自己的结果更快。
[解决办法]
wokankan
[解决办法]
学习第一,接分第二
[解决办法]
学习来的...
[解决办法]
恩,好吵!
先MARK一下.
[解决办法]
先顶再看
[解决办法]
多核多线程,才是解决之道!
[解决办法]
学习来的...
[解决办法]
今天的新帖子这么火。
从头看到尾,虽然不是很理解,但是感受颇深。
[解决办法]
学习,学习.UP
[解决办法]
路过 不是很懂
[解决办法]
好的。。。。。
[解决办法]
说实话
[解决办法]
要讨论这个问题,我觉得楼主应该要换角度来看 。
多线程的运用,最主要的目的是 “协作”。是根据需要将程序分为若干段进行执行,在加上同步完成某一只有单线程无法完成的事务。
多线程并不是用来提高CPU的运算速度。你可以回顾操作系统的发展历史,从单作业系统到多作业系统,是为了充分利用CPU,防止在某线程正在等待其他资源(除CPU)是造成的CPU浪费。只是提高了CPU使用效率,同时满足用户响应需求。
在单CPU情况下,楼主所说的分为多个线程的做法,不仅不会降低运算时间,同时CPU还得消耗时间去进行线程之间的切换。是得不偿失的。
---------
[解决办法]
要讨论这个问题,我觉得楼主应该要换角度来看 。
多线程的运用,最主要的目的是 “协作”。是根据需要将程序分为若干段进行执行,在加上同步完成某一只有单线程无法完成的事务。
多线程并不是用来提高CPU的运算速度。你可以回顾操作系统的发展历史,从单作业系统到多作业系统,是为了充分利用CPU,是防止在某线程正在等待其他资源(除CPU)是造成的CPU浪费。提高了CPU使用效率,同时满足用户响应需求。这是另一原因。
在单CPU情况下,楼主所说的分为多个线程的做法,不仅不会降低运算时间,同时CPU还得消耗时间去进行线程之间的切换。是得不偿失的。
---------
[解决办法]