V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
imherer
V2EX  ›  Go 编程语言

Go 利用多核问题

  •  
  •   imherer · 2019-06-11 14:26:40 +08:00 · 4663 次点击
    这是一个创建于 1996 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不知道怎么起标题,描述下问题

    之前是做 Node.js ,因为 Node.js 是单线程,所有之前想在一台多核的机器上充分利用 CPU 就使用 PM2 的 cluster 模式部署(作用就是可以直接启动多个实例,虽然 Node.js 里有用 cluster 模式编程,但是那样增加了编程的复杂度)

    假如我现在有一个 restful api 服务,这个服务有 A,B 两个 api,A 很耗 CPU,考虑极限情况请求 A 的时候会把 CPU 跑满

    如果用 Node.js 实现的话,部署在服务器上只启动一个实例的情况下,当用户请求 A 了之后还没 response 的情况下,另一个用户请求了 B,这时候 A 把 CPU 跑满了,B 只能等待 A 处理完

    但是如果我把这个服务部署在一个双核的服务上,然后用 PM2 启动 2 个实例后,理论上 A 还没 response 的时候 B 是不会等待的(只考虑有 2 个用户在同时发起请求)

    现在切换到 go,在一个双核的服务器上如果我只启动一个实例的情况下,go 会自动利用多核么?还是我需要用 goroutine 去自己编写代码来利用多核

    可以用一种简单粗暴的办法来启动 2 个实例:就是把这个程序复制 2 份,让他们分别监听不同的端口,然后在自己做负载均衡😂

    描述的不一定准确,但差不多就是这个意思

    18 条回复    2019-06-12 17:08:24 +08:00
    saxon
        1
    saxon  
       2019-06-11 14:33:45 +08:00   ❤️ 1
    建议先理解 goroutine 调度概念,答案是会自动 不需要额外编写代码。
    fcten
        2
    fcten  
       2019-06-11 14:42:04 +08:00   ❤️ 2
    go 标准库的 http 服务封装了 goroutine,每一个请求都在单独的 goroutine 中执行,可以利用多核,不需要自己处理。
    yuchenyang1994
        3
    yuchenyang1994  
       2019-06-11 14:42:13 +08:00   ❤️ 1
    简单说,node 是无栈协程,通过事件循环调度,go 是有调度层,是有栈的,也存在切换,完全两个概念
    qiyuey
        4
    qiyuey  
       2019-06-11 14:51:36 +08:00   ❤️ 1
    1. Stackless + EventLoop 可以是多核的,典型的如 Kotlin Coroutines。
    2. Stackfull 的 Goroutines 也是支持多核的。
    luozic
        5
    luozic  
       2019-06-11 16:54:09 +08:00
    golang 最核心的就是 mutex m:n 的 runtime。
    janxin
        6
    janxin  
       2019-06-11 16:59:26 +08:00
    支持真实多线程的语言开发理论上都可以跑满 CPU

    单线程,GIL 什么的那些的只能跑满单核
    ibreaker
        7
    ibreaker  
       2019-06-11 17:18:00 +08:00
    需要自己写代码支持
    dabaibai
        8
    dabaibai  
       2019-06-11 17:18:09 +08:00
    自动的...内部写好了
    kwoktung
        9
    kwoktung  
       2019-06-11 20:21:56 +08:00 via Android
    @yuchenyang1994 大佬。能讲的更仔细点吗。没明白
    ihipop
        10
    ihipop  
       2019-06-11 20:54:45 +08:00 via Android
    golang 的 Goroutines 是自动支持多核的
    zengming00
        11
    zengming00  
       2019-06-11 22:28:42 +08:00
    Node.js 的这个痛点在 golang 上不存在,放心用
    Mirana
        12
    Mirana  
       2019-06-11 22:39:01 +08:00
    nodejs 把计算任务切分,用 nextTick 穿起来也行啊
    tourist2018
        13
    tourist2018  
       2019-06-11 23:09:34 +08:00
    golang 里有个 SetMaxProcs 的函数(不记得是不是这样了,可以去 golang 官网查下) 现在默认都是开启满核了( go1.x 之前的版本还得手动调) 一般这个参数不用管就够了 但之前看过一篇文章 把这个参数设置为 CPU 核的倍数的 比如 16 核 可以设置最大 128 还是 256 来着 这个参数设置了 goroutine 就是跑在多核上了
    tourist2018
        14
    tourist2018  
       2019-06-11 23:10:56 +08:00
    具体优化没用到过 不过 lz 可以 google 搜一下那篇文章 很详细的
    tanrunhao
        15
    tanrunhao  
       2019-06-12 07:50:57 +08:00
    @Mirana nexttick 也没法多核运行吧,好像一个 node 就是一个进程,只能一个 CPU 跑
    Mirana
        16
    Mirana  
       2019-06-12 11:16:58 +08:00
    @tanrunhao 没法多核,但是不会让其他请求等太久,另外 nodejs 也可以 fork 一个进程去做一些计算任务
    buhi
        17
    buhi  
       2019-06-12 17:07:02 +08:00
    nodejs 一个进程只能利用单核, 但是因为有事件循环, 所以当一个请求在处理 io 的时候也可以处理另外一个请求, 并不是只能等在那里
    buhi
        18
    buhi  
       2019-06-12 17:08:24 +08:00
    看错了 说的是把 CPU 跑满的任务, 那还是 go
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3155 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 13:15 · PVG 21:15 · LAX 05:15 · JFK 08:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.