Golang


Golang的GPM调度模型,多个G即goroutine,是建立在线程之上还是进程之上?

据资料,P为逻辑处理器,M为机器cpu核心数(不是物理核心数,如果有超频,则是超频后的cpu数量),两者数量一致。

用代码验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

package main

import (
"fmt"
"sync"
)

func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for {
fmt.Println("A:", 1)
}
}()

wg.Wait()
}

运行上述代码go run t.go,而后查看活动监视器


使用runtime.GOMAXPROCS(num)来设置允许该程序使用的cpu数量,最早版本默认为1,后来改为机器的(逻辑)cpu数。所以不设置,就等同于runtime.GOMAXPROCS(runtime.NumCPU())


查看进程的线程列表:

参考: mac 进程和线程工具

故而,GPM中的M实际指线程。通过抽象,在用户级别实现了m个goroutine和n个线程之间的对应(一般m远远大于n)


更多关于golang的调度,可参考:

6.5 调度器

Go goroutine理解


nginx


典型的多进程处理模型

启动ngnix后,查看 活动监视器 如下:


此处的2个用户为nobody的工作进程,在nginx.conf中设置:


php


同nginx一样,php-fpm也是多进程模式:

可以查看并修改PHP-CGI进程的数量


redis服务端


面试常问,redis(服务端) 的所谓单线程,指的仅仅是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程。且最新版本中,网络请求模也支持多线程

参考: 为什么 Redis 选择单线程模型


mysql服务端和postgresql服务端


两大数据库显著差异之一,就是mysql通过多线程方式,实现高并发;而pg和nginx类似,使用多进程方式。

如下:

所以mysql有线程池的说法。

而对于pg: