对于单核 cpu 而言,开多线程的目的难倒只能是为了防止阻塞么?

2015-11-11 20:25:32 +08:00
 aiqier

以下是一些单核 cpu 多线程的疑问,求解答(都指单核)。
1.如果一个进程有 n 个任务要处理,因为终究是在一个 cpu 上跑,所以这 n 个任务在一个线程还是多个线程上跑,执行的总时间是一样的(多线程,线程切换可能更浪费时间)?
2.是否进程开多线程就能抢到更多的 cpu 时间, python 这种带 GIL 的估计是没戏了,那么 java 呢?
3.自己抢到更多 cpu ,机器上的其它程序不就 cpu 时间少了么?是因为 cpu 大部分时间都是空闲的,不怕抢?还是因为在做应用层开发的时候,是不用考虑其它程序能不能抢到 cpu 时间的。
4.一个进程所有线程能抢到的时间片总和是有最大值吗?一个线程一次能拿到多长的 cpu 时间?
综上,我的最大疑问就是:对于单核 cpu 而言,开多线程难倒只能防止阻塞么?

13873 次点击
所在节点    程序员
34 条回复
congeec
2015-11-12 00:29:13 +08:00
@adadafa 抱歉还是没说清楚。用单核 cpu 的系统不可能有真正的多进程,虽然咱可以调用多进程 API ,但那是假的。楼上也说了,现在 cpu 是靠分配时间来分配资源,在切换( switch )到另一个任务( task )的时候,上一个任务的上下文) context )要保留下来,如此往复。这和线程有什么区别?所以,所谓的进程、线程、协程都是线程(thread), 一层套一层。明白人为了区分他们搞出来一大堆新术语,结果大家更迷了。你说的最后一句很对,单核只有 concurrency ,没有 parallelism 。可以去搜搜 Linus 为什么喷“ parallel 浪费大家时间”。
sgissb1
2015-11-12 01:14:28 +08:00
LZ ,你没有完全理解多线程的意义。或者没有完全理解什么是多线程,包括现在很多写代码的人,总在说多线程,有时候甚至把多线程和多并发或者多线程和多吞吐处理给混为一谈。

首先说一下一个进程里面为何要开多线程问题,和 cpu 是否多核,或者主板是否多路 cpu 关系是有的,但也是有限定条件的,具体内容如下:

1 ,由于部分 api 不支持异步方式执行,仅仅支持同步执行。例如读取一个文件,当每次读取的文件的数据很大时,内存缓存中没有足够的内存提交给调用者,这时 api 或者操作系统会代用户去从磁盘上读取文件,而磁盘相对于内存和 cache 来说属于慢速设备,并且在操作系统调度层面,对于此类操作是,现成被阻塞住(即挂起),然后转为执行其他任务。
为了让整个进程不进入假死(僵死)情况,需要在开一个线程来维持其他任务的执行。

2 ,在多路 cpu 的系统中,多线程可以提高任务处理的效率。即理想情况下,每个线程独占一路 cpu 处理能。

3 ,特殊多路系统,在非对称多路系统中,每个线程(进程)都执行在不同的核上,所访问的硬件资源不同,所以需要开多个线程。

至于你说的抢 cpu 执行时间问题,要分操作系统看,目前我们常用的 windows 和 linux 都是抢占式操作系统。对于 linux 我不是很熟,对 windows 略知一二:

1 ,操作系统调度粒度是线程+进程。即操作系统调度的最小单位是线程,但是否决定该线程执行,除了看线程执行时间和未执行间隔以外,还需要看总进程内的执行情况。
其中还存在进线程优先级问题,中断优先级, cpu 执行平衡问题,就近执行原则等。

2 ,一个进程中,线程并非越开越多就好。因为非分时的非实时操作系统的任务调度周期很有可能是不准的,操作系统是否要打断一个线程的执行,转而交给另外一个线程执行,除了调度周期到来的调度扫描,还有任务执行的优先级, IRQL 级别,线程处于什么状态等。

3 ,过多的线程不仅不能抢到有效的 cpu 执行时间,还会导致线程环境切换的浪费。因为每次线程的切换其中伴随的态转换,以及堆栈移动、寄存器恢复、内存调度等问题。频繁切换线程,只会得不偿失,不管是 python 或者 java 或者 c++或者 c#都是一样的,因为是操作系统在管理线程执行。

至于你提出的第四个疑问,在单核 cpu 里面开多线程的事情。我只能和你说,设计决定一切。
theoractice
2015-11-12 07:36:36 +08:00
单核纯计算不要开多线程。有 io 的话性能瓶颈可能不在 cpu 上。参考 amdahl 定律。
br00k
2015-11-12 09:01:20 +08:00
@congeec P4 就有单核超线程。 MIPS 产品也有,有些架构还有单核四线程或更多的。
congeec
2015-11-12 09:18:40 +08:00
@br00k 涨姿势了,谢谢。:D
zhangdawei
2015-11-12 09:43:44 +08:00
CPU 快, IO 慢,不多线程, CPU 效率不高,操作系统效率也不高。
aiqier
2015-11-12 10:22:30 +08:00
@chairuosen 这什么意思。。。大多程序只跑一个核?
aiqier
2015-11-12 10:26:20 +08:00
@Codist 感谢, 最后一句是“并不一定”么?
aiqier
2015-11-12 10:36:29 +08:00
@sgissb1 那么是不是说,瓶颈如果是 io ,使用异步 io ,比如 nodejs , nginx , epoll ,之流比多线程更合适?
yuchting
2015-11-12 11:18:41 +08:00
@sgissb1
@leavic
两位说的很清楚了。感觉楼主把多线程和多核搞混了,把操作系统和执行程序搞混了。这个可能和和市面上的多核宣传有关系吧,多核就可以一边看电影一边压缩文件之类的宣传,然后把单核或者少核鄙视一把,让人们更新换代,增加自己的销量。
还有一个叫多任务的概念,是对比以前 DOS 系统的单任务,也是宣传。
计算机科学貌似在很早很早的时候,就进行了时分多任务的改进了,和多核没关系,唯一的目的就是让 cpu 的空闲时间变少(等待用户操作,等待网络、磁盘等输入输出设备 io)。
而这个改进是操作系统完成的,和硬件关系相对较少。如果真的有兴趣想理解计算机,操作系统和编译原理的基础知识必不可少。
说完了。
sgissb1
2015-11-12 11:34:45 +08:00
@aiqier 兄弟,你的代码功底还有待加强。你问的这个问题,我没法给你答复。

我说了设计决定一切
Codist
2015-11-12 12:49:59 +08:00
@aiqier 噢,是
SIFT2009
2015-11-12 14:27:21 +08:00
单核要跑多线程,有多大意义?
kaneg
2015-11-14 18:00:05 +08:00
多线程对 GUI 程序非常有用,因为没有多线程支持, javascript 要实现一个 并行的任务有多难

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/235443

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX