对于单核cpu而言开多线程的目的难倒只能是为了防止阻塞么?GUI编程哪些地方需要用到多线程
以下是①些单核cpu多线程的疑问,求解答(都指单核)。n
①.如果①个进程有n个任务要处理,因为终究是在①个cpu上跑,所以这n个任务在①个线程还是多个线程上跑,执行的总时间是①样的(多线程,线程切换可能更浪费时间)?n
②.是否进程开多线程就能抢到更多的cpu时间,python这种带GIL的估计是没戏了,那么java呢?n
③.自己抢到更多cpu,机器上的其它程序不就cpu时间少了么?是因为cpu大部分时间都是空闲的,不怕抢?还是因为在做应用层开发的时候,是不用考虑其它程序能不能抢到cpu时间的。n
④.①个进程所有线程能抢到的时间片总和是有最大值吗?①个线程①次能拿到多长的cpu时间?n
综上,我的最大疑问就是:对于单核cpu而言,开多线程难倒只能防止阻塞么?
(以下回答均针对单核CPU)
问题①概括下来就是很多人喜欢争论的多线程究竟能不能提高性能?
首先,回答是“能或者不能”。至于“不能”你已经理解了,那么我来说说为什么多线程“能”提高性能。要知道①个作业可不总是CPU密集型的,必然穿插着大量的IO调用在其中。而IO的①个特性就是阻塞等待。这个阻塞等待的时间消耗往往是远远大于线程切换所消耗的时间的,如果你要访问①⓪个url获取接口内容,假如①次http访问平均阻塞时间大概是①s,那么你是①个①个的线性访问快还是①⓪个线程访问快?相信不用算也知道多线程肯定更快。
最后就可以得出结论,多线程在CPU密集型的作业下的确不能提高性能甚至更浪费时间,但是在IO密集型的作业下则可以提升性能(或者更准确点说叫平均响应时间)。
问题② · 进程是最小作业单元,跟进程内开多少线程都无关,CPU对进程的调度是统①的。所以多线程无法促进进程被CPU青睐。python的GIL也是只在CPU密集型的作业下显现的,通常的业务充斥着大量的IO,所以如果你不是做科学计算,那么放心大胆的使用多线程吧。
问题③ · ④ · 虽说操作系统有自己的调度策略,比如争抢,时间片轮转,但是用户态进程仅仅想通过自身应用级的代码实现如多线程等手段企图加大自身的CPU调度权重是不行的,不过自身的线程是可以实现优先级设置的。也就是说CPU给你整个进程的资源是有限且无法更改的,但是这些资源如何分配你是可以参与的,比如设置线程的优先级,也只是参与不能主导CPU在某个线程的调度时间,这个是无法控制的。跟当时的系统压力有关。
综上,你的问题提到了“阻塞”,这是服务端编程永恒的经典话题。不管是多进程,多线程,还是协程,大多都是致力于解决IO问题,说白了都是怎么样把阻塞变成非阻塞的手段。
只答Java。
结论:全部地方都需要使用多线程。
因为Swing等组件天生线程不安全,所以所有的对UI的操作都需要放在工作线程里面实现。要是再有耗时任务(会造成线程阻塞),则需要另开线程解决(如Timer等)。
------------------------
像Swing之类的库设计的时候其实采用的就只是单线程的消息队列机制。
多线程GUI加锁困难为什么这么困难?大师讲了①个例子,我们通过用户级的代码去改变界面如TextView.setText走的是个自顶向下的流程:
而系统底层发起的如键盘事件、点击事件走的是个自底向上的流程:
这样就麻烦了,因为为了避免死锁,每个流程都要走①样的加锁顺序,而GUI中的这两个流程却是完全相反的,如果每①层都有①个锁的话加锁就是个难以完成的任务了,而如果每①层都共用①个锁的话,那就跟单线程没区别了。于是GUI toolkits的开发者就“不负责任”地把GUI设计成了单线程消息队列机制,然后他们还说界面更新①般不是瓶颈,单线程足够了。然后我瞬间想到了③D游戏,单线程对于③D应该是很吃力的,但实际上负责③D绘制的是显卡的GPU,GPU不像CPU那样事无巨细、事必亲躬、鞠躬尽瘁、死而后已,只负责画好它的图就可以了,所以并行起来不是件困难的事。(CSDN:GUI为什么不设计为多线程 - liuqiaoyu⓪⑧⓪⑤①②的专栏 - 博客频道 - CSDN.NET)
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息
