对于单核 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 而言,开多线程难倒只能防止阻塞么?

13619 次点击
所在节点    程序员
34 条回复
aruisi
2015-11-11 20:39:08 +08:00
我也有这疑惑,不知单核 cpu 跑程序编译时要不要开启多线程。
kamushin
2015-11-11 20:45:55 +08:00
写个应用程序, 就准备跑在单核上?
feikaras
2015-11-11 20:48:37 +08:00
为什么用 python , java 那么慢的语言却在操心操作系统的调度开支?
pythonee
2015-11-11 20:51:56 +08:00
吞吐量
webflier
2015-11-11 20:54:28 +08:00
通常一个任务不光 cpu 上要花时间, io 上也要花时间(不如去数据库查数据,去抓网页登)。
一个进程在等 io 的时候, cpu 是闲置的,另一个进程正好可以利用 cpu 把 cpu 该做的事做完。
多几个进程一起跑,可以把 io 和 cpu 都跑满了。
大概就是这个意思
br00k
2015-11-11 21:10:32 +08:00
充分利用 CPU 空闲啊。超线程技术也是一样。
Ouyangan
2015-11-11 21:14:20 +08:00
@feikaras java 不慢了....
jonah
2015-11-11 21:25:30 +08:00
如果自己实现任务 A 阻塞时去运行 B ,效率有可能比多线程要高,多线程就是把这种调度转交给了操作系统。而且还有设计和逻辑上的便利,比如一个线程负责一个不同类型的工作。
ryd994
2015-11-11 21:33:33 +08:00
看是什么认为。如果完全是 cpu ,开多线程只会更慢。上下文切换的开销。
抢 CPU 时间前提是同一优先级。如果其他进程优先级高,那怎么抢都抢不到。

@jonah 这不就是协程么
lzhip
2015-11-11 21:34:15 +08:00
1 、不一定,多线程可以在 io 的时候切换到其他线程执行。如果单线程那就只能等了。
2 、一般是的,一个要看你线程的操作。一般你在单核机器上写一个死循环,基本整个机器都卡了。但是如果你起下次一百个线程都是 sleep ,那也不会太占用 cpu 。另外操作系统调度线程不依赖进程。
3 、当然要考虑啊!要不把用户机器卡死了,人家就不用你的程序了。
4 、看什么平台吧, windows 好像不支持抢占。线程只能被系统调用。
chairuosen
2015-11-11 21:42:11 +08:00
xuyinan503
2015-11-11 21:54:46 +08:00
真是 iV2ex 啊,这都能黑到 windows
aalska
2015-11-11 21:55:54 +08:00


这图不错
HentaiMew
2015-11-11 21:56:32 +08:00
@feikaras java 早就不是黑执行效率了,它在有 GC 功能语言中已经算足够快的了。 Java 该黑的是它的内存消耗....
yuelang85
2015-11-11 21:58:01 +08:00
是的,就是为了防止堵塞。
aruisi
2015-11-11 22:05:52 +08:00
@chairuosen 神了,这是奔腾 D 吗
Codist
2015-11-11 22:50:21 +08:00
1 、如果一个进程执行 N 个任务,而这些任务又属于 I/O 型的任务,通过 CPU 的调度是可以提高效率的,通常网络 I/O 阻塞的时间比线程 context switch 的时间要长多了。
2 、在 Linux 下线程进程的调度策略相同,如果一个进程中包含更多线程的话,我猜会拿到更多的执行时间。 CPython 的 GIL 只是给多线程的执行加了锁,限制了多线程的并行执行,单核下 GIL 应该就跟没有一样。

 3 、 CPU 的计算速度太快了,进程的调度已经比较完善,通常应用层面程序不需要考虑底层进程的调度对程序的影响,但是要考虑程序 CPU 资源的消耗,写一个死循环跑一会儿 CPU 都能煎鸡蛋了。
大多数情况下 CPU 的计算都是不饱和的,通常服务器 CPU 利用率达到 80%的时候就要扩容了。
4 、没有听过类似这种限制,太细的东西不清楚。
开多线程并一定是为了性能,很多场景下你的业务逻辑是并发的,所以你的程序逻辑也是并发的。
congeec
2015-11-11 23:08:48 +08:00
你说的是系统级的线程还是 CPU 级的线程?照你的描述,你想表达的是多进程。一句话,单核 CPU 没法跑系统级的多进程。单核多线程主要是为了增加 I/O 利用率。如果有支持超线程技术(HT)的单核 CPU ,请告诉我。
线程的概念其实有些模糊,比如: CPU 级线程就是操作系统级进程。程序自己也可以把系统级线程看做进程,并自己实现多线程。这种程序自己实现的多线程就是所谓的协程(coroutine)或纤程(fiber thread)。
adadada
2015-11-11 23:48:26 +08:00
@congeec 这里的“系统级的多进程”指的是操作系统内核实现的进程还是 CPU 的 HW Thread ?如果是前者,操作系统的还是可以实现多进程的啊?只是这样的多进程只具备 currency 而不具备 parallelism 。
leavic
2015-11-12 00:03:23 +08:00
我仅仅从一个 5 年单片机码农所理解的角度回答一下这些问题:

1.如果一个进程有 n 个任务要处理,因为终究是在一个 cpu 上跑,所以这 n 个任务在一个线程还是多个线程上跑,执行的总时间是一样的(多线程,线程切换可能更浪费时间)?

A :对于单核 CPU 来说,所谓的线程,就是 task , CPU 就是依靠调度器在这 N 个 task 之间来回切换,同一时刻只有一个 task 在运作。

2.是否进程开多线程就能抢到更多的 cpu 时间, python 这种带 GIL 的估计是没戏了,那么 java 呢?

A :这个涉及到操作系统的设计原理, windows 和 linux 本质上都不是实时系统,如何分配 CPU 时间在不同的操作系统上有不同的规则,一般来说是按优先级分配。但你一个人开了多个任务,总概率上讲分配到更多 CPU 资源的概率是更高的。

3.自己抢到更多 cpu ,机器上的其它程序不就 cpu 时间少了么?是因为 cpu 大部分时间都是空闲的,不怕抢?还是因为在做应用层开发的时候,是不用考虑其它程序能不能抢到 cpu 时间的。

A:这个取决于你应用到底能 CPU 密集到什么程度,对一般的应用来说,你是不需要担心别的程序没有 CPU 资源可用的,唯一需要注意的是避免进入死循环,在单片机中,中断里出现一个死循环的结果就是占用全部 CPU 资源。

4.一个进程所有线程能抢到的时间片总和是有最大值吗?一个线程一次能拿到多长的 cpu 时间?
综上,我的最大疑问就是:对于单核 cpu 而言,开多线程难倒只能防止阻塞么?

A :这个依然取决于操作系统的设计。对于单核 CPU 而言,多线程是几乎唯一合理的利用 CPU 资源的方式,一颗 CPU 如果只有一个线程,那基本就是个弱智级别的 CPU 。

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

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

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

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

© 2021 V2EX