V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yakczh
V2EX  ›  程序员

线程和进程在运行性能上是不是一样?

  •  
  •   yakczh · 2015-05-06 10:43:49 +08:00 · 5228 次点击
    这是一个创建于 3501 天前的主题,其中的信息可能已经有所发展或是发生改变。

    除了内存占用不说, 比如同一个任务,一个用多线程方式,一个用多进程方式处理,最后运行时间有差别吗?

    31 条回复    2015-05-08 07:08:02 +08:00
    moonpie
        1
    moonpie  
       2015-05-06 10:46:00 +08:00
    非程序员路过
    zerh925
        2
    zerh925  
       2015-05-06 10:49:09 +08:00
    ehhh, it depends.
    信息不足,如果能给出具体案例更方便讨论。
    ipconfiger
        3
    ipconfiger  
       2015-05-06 10:50:03 +08:00
    posix 的调度单位是线程,进程只是容器而已,所以在调度上不存在效率上的差别,只是5个线程在1个进程里和5个线程在5个进程里消耗的内存要多一些
    Andiry
        4
    Andiry  
       2015-05-06 10:54:19 +08:00
    进程间切换比线程切换开销大
    cfan8
        5
    cfan8  
       2015-05-06 10:54:37 +08:00
    如果考虑到线程/进程通信的话,必然线程快

    如果考虑到Robustness的话,线程一个挂了就炸了,进程的话比较好恢复,总时间可能更少
    zhipeng
        6
    zhipeng  
       2015-05-06 11:00:57 +08:00   ❤️ 4
    Windows里的进程线程模型是,进程是线程的容器,程序执行都是以线程为单位的。
    Linux中只有进程,线程只是没有独立虚拟内存空间的进程。
    从运行时间上来看我感觉不会有太大差别。但考虑到创建进程的代价大于创建进程,并且线程间通信比进程容易(同一个进程中的线程有公共的地址空间,公共的地址空间也可以使得CPU的cache能更好发挥作用),如果这类操作十分多,最终可能导致多线程处理快一点。
    yakczh
        7
    yakczh  
    OP
       2015-05-06 11:02:10 +08:00
    @cfan8  不涉及通信,就是任务处理和切换调度
    wy315700
        8
    wy315700  
       2015-05-06 11:04:31 +08:00
    补充一句。

    Python还是不要用多线程了。
    endrollex
        9
    endrollex  
       2015-05-06 11:06:11 +08:00
    不算管理开销,运行时间没差别
    neoblackcap
        10
    neoblackcap  
       2015-05-06 11:10:18 +08:00   ❤️ 2
    同@zhipeng 所说的一样,linux下面的进程跟线程差别很少,他们底层实现的代码有90%是相同的,创建成本差异几乎忽略.不过这个放在windows就很不一样了,windows的进程很重量级,需要消耗比线程更多的资源才行
    zzxworld
        11
    zzxworld  
       2015-05-06 11:27:52 +08:00   ❤️ 1
    要了解他们之间是否存在性能上的差别,那首先需要对这两个名称有个大概的概念。就拿工厂和工人来比喻好了。工厂是进程,工人是线程。那么把楼主的问题转换过来,就是有这样两队人,要进行生产大比武:

    豪豪队,有 5 个工厂,每个工厂配 1 个工人
    穷穷队,有 1 个工厂,工厂配 5 个工人

    貌似不相上下,反正单位时间类的工作处理量都是 5。这时候就是看作务的时候了。

    如果咱们再加上一些任务条件:

    比如:每队做 5 个盒子。这个应该两队不相上下。

    又比如:两队的工厂都一样大,面积 5 平方,然后每队都要做 1000 个纸盒子。这时候,穷穷队从哪方面都不占优呀。

    不知道有没有解决题主的疑惑,就这样吧。话说,用 python 的我一看到进程就会有种莫明的忧伤。
    aphay
        12
    aphay  
       2015-05-06 15:03:53 +08:00
    那人们还发明线程干嘛?
    ipconfiger
        13
    ipconfiger  
       2015-05-06 15:17:08 +08:00   ❤️ 1
    线程是操作系统的调度单位,进程是资源的持有单位,不要混为一谈好不好,不懂的去看posix 标准先
    wind3110991
        14
    wind3110991  
       2015-05-06 15:58:47 +08:00
    @aphay 也不能这样说,我的理解是:linux的内核态就是用守护进程(内核线程)去周期性维护页面置换,高速缓存,网络连接等操作的,而一般的进程要通过系统调用去创建,用进程切换去维护这些东西显然开销太大了
    tabris17
        15
    tabris17  
       2015-05-06 16:03:10 +08:00   ❤️ 1
    线程和进程的最主要区别是前者共享同一进程的内存,后者不同进程内存隔离
    kaizixyz
        16
    kaizixyz  
       2015-05-06 16:11:19 +08:00
    进程切换开销大~
    线程切换开销小~

    所以线程给用户带来最直观的体验就是响应速度快~

    延引@zzxworld的例子

    假定:
    你是老板~
    你准备生产产品A~
    产品A需要a1,a2,a3。。。an等零件组成~

    plan1:开n个工厂~只招1种技工~
    plan2:开1个工厂~招n个不同的技能的工人~

    哪个划算~
    yakczh
        17
    yakczh  
    OP
       2015-05-06 16:50:10 +08:00
    @kaizixyz 问的不是划算,是两个plan里面的工人干起活来速度有没有区别
    cpp255
        18
    cpp255  
       2015-05-06 17:45:54 +08:00
    进程间的通信比线程要麻烦。
    tabris17
        19
    tabris17  
       2015-05-06 17:52:48 +08:00
    进程切换开销大~
    线程切换开销小~

    ================

    没这种说法
    raincious
        20
    raincious  
       2015-05-06 17:58:11 +08:00
    @tabris17

    嗯。这个跟操作系统(进程如何Fork)有关,还和具体需要做的事情有关(比如加个锁)。

    还有就是 @cpp255 进程间通讯,是用共享的内存区还是其他方案。
    http://en.wikipedia.org/wiki/Inter-process_communication

    另外,除了性能,多进程的程序不太需要担心一个子进程挂了(程序员需要担心),而多线程的一个挂了基本上整个进程就危险了。
    raincious
        21
    raincious  
       2015-05-06 18:00:50 +08:00
    @raincious

    补充下
    > 进程切换开销大~
    > 线程切换开销小~

    这个需要看操作系统的进程调度,这样归类是不太准确的。

    (这可能是在说比如Windows?)
    tabris17
        22
    tabris17  
       2015-05-06 18:39:14 +08:00   ❤️ 1
    @raincious Windows我可以很确信,没有这种说法。windows下CPU最小任务是就是线程(纤程不算),每个线程一个TEB结构,一个线程切换到同进程的另一个线程和一个线程切换到不同进程的另一个线程的开销是一样的(不考虑上下文切换的CPU缓存)
    riaqn
        23
    riaqn  
       2015-05-06 19:10:03 +08:00
    @zhipeng 你说的是CPU里的内存cache么..至少x86的cpu都是以物理地址为索引来cache的, 所以和地址空间是不是同一个关系不大.
    但是TLB确实会受这个影响, 同一个地址空间, 意味着线程之间切换不需要刷TLB, 所以理论上会快些.
    zhipeng
        24
    zhipeng  
       2015-05-06 19:35:59 +08:00
    @riaqn 不同进程的地址空间对应的物理地址不同吧,所以cache效果会比多线程弱一些
    riaqn
        26
    riaqn  
       2015-05-06 22:35:10 +08:00
    @zhipeng 如果是同一个程序, 则所有.text 以及.rodata之类的段都会映射到同一个物理内存.
    semicircle21
        27
    semicircle21  
       2015-05-06 23:47:58 +08:00
    @riaqn
    @tabris17
    1. 线程切换不需要切 TLB, 至少 Linux 是这样, 如果 Windows 不是这样, 那就太颠覆了...
    2. 对进程而言, 不同进程的数据段(.data)肯定不在一起, 增加各种 cache invalid 的概率, 甚至到虚拟内存. 线程的数据段肯定是尽量拼在一起的, 会减少这些发生的几率.
    3. 两者相同的开销也有很多, 比如都要陷入内核, 保存寄存器状态等. 所以究竟上述开销能不能"忽略不计", 我觉得需要量化评价了, 不同处理器架构肯定不同. 而且, 要面向具体问题, 比如说 内存, CPU Cache 超大, 原超应用所需内存的场景, 在这种极端情况下, TLB 什么的也根本不重要了.

    主观上, 我觉得这个两种的区别一般是不能忽略不计的.
    xieyudi1990
        28
    xieyudi1990  
       2015-05-07 06:31:26 +08:00
    @riaqn "至少x86的cpu都是以物理地址为索引来cache的"
    你有资料说明这点吗? 据我了解 cache 多是 VIPT 的, 至少我印象中 x86 的 Opteron 是 VIPT的 (虽然低12位不参与 TLB 转换, 但如果不是 PIPT 的, 也不能这么说吧)
    riaqn
        29
    riaqn  
       2015-05-07 07:34:27 +08:00
    @xieyudi1990 不好意思, 我又查了一下, intel确实基本上是VIPT的.
    @semicircle21 至于线程和进程切换的cost比较, 一般都认为前者较小. 主要问题是小多少, 这一个问题我觉得没有测试以及特定的应用,是很难得出结论的.
    而你说的.data, 考虑到一般是保存全局变量, 而.data本身不会很大, 而且对其的访问也不会很频繁, 所以我觉得不是很大的影响因素.
    tabris17
        30
    tabris17  
       2015-05-07 09:42:08 +08:00
    @semicircle21 进程切换唯一可能带来的大开销是由于切换页表可能会导致的重新映射页表,但是如果内存足够大,是可以避免发生这种情况的
    semicircle21
        31
    semicircle21  
       2015-05-08 07:08:02 +08:00
    @riaqn 我的基础知识也喂狗了, 不是 .data...我的意思是所有运行时数据, 包括 heap, stack 这些...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3614 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:25 · PVG 12:25 · LAX 20:25 · JFK 23:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.