V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
LinJunzhu
V2EX  ›  Linux

多线程可以同时使用 CPU 的多个核心?

  •  1
     
  •   LinJunzhu · 2016-06-14 10:33:28 +08:00 · 28031 次点击
    这是一个创建于 3119 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我们知道,单核 CPU 在同一时间内只能够运行一个进程。而在同一时间内也是只能够运行同一个线程,只不过由于时间片轮转的制度才让我们看起来像同时运行多线程。

    但昨天在网上搜的资料让我有点懵,有这样的观点:

    「单进程多线程可以同时用到 CPU 的双核心」

    一直以来我都是认为, CPU 的双核可以同时 hold 住两个进程,但是跟线程并没有关系吧??

    不知道大家是怎样认为的?

    第 1 条附言  ·  2016-06-21 14:42:18 +08:00
    既然多线程可以利用到 CPU 的多核多线程。

    那我现在有个 project, 我直接开 单进程多线程 不就可以了吗?多进程还有存在的必要?
    21 条回复    2016-06-24 20:49:39 +08:00
    Neveroldmilk
        1
    Neveroldmilk  
       2016-06-14 10:41:34 +08:00   ❤️ 1
    CPU 工作的分配一般是以线程为级别的,只不过大部分程序一个进程只用一个线程,所以看起来好像 CPU 只能是以进程位粒度分配任务。
    fds
        2
    fds  
       2016-06-14 10:45:56 +08:00   ❤️ 4
    摘抄:总而言之:进程是组织资源的最小单位,而线程是安排 CPU 执行的最小单位。
    http://www.cnblogs.com/CareySon/archive/2012/05/04/ProcessAndThread.html
    bingliu221
        3
    bingliu221  
       2016-06-14 10:46:11 +08:00   ❤️ 1
    进程描述的是资源分配的单位,一个进程里面的所有线程都可以共享这些资源。
    线程是 CPU 调度的单位,一个逻辑 CPU 核心在某一时刻只能 hold 住一个线程。

    操作系统原理的基础内容,楼主可以找本书过一下。
    好久没碰这些概念了,不知道我说得有没有严谨。
    vexxx
        4
    vexxx  
       2016-06-14 11:05:38 +08:00
    讲个通俗不严谨的说法, CPU 看到的是线程,看不到进程,进程是 OS 上的概念。与 lz 之前的想法恰恰相反。
    ryd994
        5
    ryd994  
       2016-06-14 11:27:52 +08:00 via Android
    在 Linux 里,创建新进程和新线程可以用同一个系统调用,唯一的区别是,创建新线程时不创建行调用栈。而且你仔细看, tid 和 pid 其实是在同一个范围里
    主进程 tid=pid
    子进程很多时候就是主进程 pid+n
    而后面其他新进程会顺延下去
    所以,其实进程和线程的区别只在于内存空间是不是共享而已………
    2225377fjs
        6
    2225377fjs  
       2016-06-14 11:30:25 +08:00
    多线程当然可以利用多核,调度单元是线程,不是进程。
    不然 Java 程序的 1600%的 CPU 利用率是怎么跑出来的。。?(同时占满 16 个 CPU 核心)
    shrimp929
        7
    shrimp929  
       2016-06-14 11:49:04 +08:00
    对于 CPU 而言,看到的是线程,多核 CPU 可以同时调度多个线程执行。我想楼主可能不是很理解线程的意义把。一个进程有多个线程的好处:对于单核 CPU 而言,CPU每次只能调度 1 个线程,但是若当前线程阻塞了, CPU 可以不必等待,而是先调用别的线程执行,这样就提高了 CPU 的利用率
    VVJiao
        8
    VVJiao  
       2016-06-14 12:12:32 +08:00
    你需要搞明白并发 concurrent 与并行 parallel 的区别
    SakuraSa
        9
    SakuraSa  
       2016-06-14 12:32:44 +08:00
    被 GIL 锁住的 python 流下了悲痛的眼泪……
    zhicheng
        10
    zhicheng  
       2016-06-14 12:54:43 +08:00   ❤️ 6
    “你认为” 和 “大家认为” 怎么样并没有用,不如多看看书。

    最早 UNIX 的调度是以 “进程” 为最小调度单位,那个时候还没有线程的概念。线程有两种,一种是 “用户态线程” ,对内核不可见,内核不可以调度,现在一般叫做纤程或协程。另一种是 “内核态线程”,由内核调度,也称作轻量进程 LWP 。现在说的线程,一般不特殊指定,都是内核线程。

    能不能利用多核的关键是能不能被内核调度,既然内核态线程可以被调度,自然可以利用多核。

    另外只要资源足够(内存) CPU 可以 hold 住任意多的进程或线程,这与 CPU 的核数无关。你在这里指的应该是 “运行” 。
    owt5008137
        11
    owt5008137  
       2016-06-14 13:00:16 +08:00 via Android
    赞同 @zhicheng 的说法,并且现在的操作系统内核的话答案基本上都是可以。
    linux , unix like 的大多数内核和 windows 都可以
    ceyes
        12
    ceyes  
       2016-06-14 13:15:27 +08:00
    tkisme
        13
    tkisme  
       2016-06-14 15:20:27 +08:00
    lujun9972
        14
    lujun9972  
       2016-06-14 17:09:01 +08:00
    @zhicheng 的解释很到位, kernel thread 可以利用多 CPU , user thread 不能利用多 CPU
    sitelogin
        15
    sitelogin  
       2016-06-14 17:50:00 +08:00
    进程是空间,线程是时间
    FrankHB
        16
    FrankHB  
       2016-06-20 09:18:53 +08:00
    “单核 CPU 在同一时间内只能够运行一个进程”当然是错的。“单进程多线程可以同时用到 CPU 的双核心”在主流操作系统上没有问题。
    因为同时多线程(SMT),现代超标量处理器(一个 CPU 物理核心)可以同时跑超过一个线程(否则执行单元空着太浪费),例如 Intel 的 hyperthreading 支持一个物理核心跑两个线程。讲几核的 CPU 的核心数一般直接指物理核心数,如果是指逻辑核心数一般直接会说线程数,几个逻辑核心就同时支持几套架构状态和几个线程。
    对操作系统内核 /执行体来说,直接可见的 CPU 资源是逻辑核心,可以调度的任务一般直接实现成 CPU 支持的线程,所以单核 CPU 可以同时跑多个任务。不同操作系统中任务的概念不一样。例如 Windows NT 调度的是线程,进程只是线程的容器; Linux 内核不区分进程或者线程,调度的任务在用户空间可以被实现成一个进程或进程中的线程。
    注意用户空间的线程和 CPU 上跑的线程不是一回事,只不过流行的系统很多直接采用 1:1 映射简化实现罢了。
    LinJunzhu
        17
    LinJunzhu  
    OP
       2016-06-21 14:41:15 +08:00
    一个星期没上来看,看到大家这么热心的回复,很是感谢,也明白了一些概念。

    现在又有一个新的问题:

    既然多线程可以利用到 CPU 的多核多线程。

    那我现在有个 project, 我直接开 单进程多线程 不就可以了吗?多进程还有存在的必要?
    LinJunzhu
        18
    LinJunzhu  
    OP
       2016-06-21 14:42:01 +08:00
    zhicheng
        19
    zhicheng  
       2016-06-21 18:51:08 +08:00 via Android
    你先去看一下书再来提问吧,随便一本操作系统原理都可以。

    现代操作系统进程代表的是地址空间 (Address Space)。目的是隔离,一个进程不可以直接访问另一个进程的内存空间,这是由操作系统内核保护的。

    估计你要问为什么隔离?我不告诉你。自己看书。
    LinJunzhu
        20
    LinJunzhu  
    OP
       2016-06-24 16:47:39 +08:00
    @zhicheng

    唔.. 其实你说的这些我也懂。

    只是突然有点疑惑,那这样的话是 「多进程单线程」 的效率高还是 「单进程多线程」 的效率高。

    多线程的话考虑到会抢占资源,所以会有锁的存在,影响效率
    多进程的话由于要 fork 两份一模一样的数据,并且要 CPU 要切换进程,也会耗费不少资源

    不过这还是要根据不同情况分析。如果是 Python Ruby 等有 GIL 锁的语言,那肯定是多进程的效率要更优。

    谢谢啦 :)
    zhicheng
        21
    zhicheng  
       2016-06-24 20:49:39 +08:00 via Android
    @LinJunzhu 不,你不懂。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2570 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:39 · PVG 18:39 · LAX 02:39 · JFK 05:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.