Golang


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

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

用代码验证:

package mainimport (    "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 抉择单线程模型

redis网络IO模型



mysql服务端和postgresql服务端


两大数据库显著差别之一,就是mysql通过多线程形式,实现高并发;而pg和nginx相似,应用多过程形式。

如下:

所以mysql有线程池的说法。

而对于pg:




过程有独立的地址空间,线程则没有独立地址空间. 同一个过程的不同线程, 它们之间共享地址空间的.

对于多过程模型, 因为之间互相独立, 其长处就是安全性比拟好. 一个过程的crash, 不会导致整个软件的解体;而线程则不行,一个过程里的某个线程crash,会影响整个过程.

多过程的毛病, 是其创立和上下文切换的开销比拟大, 另外过程之间要想互相通信须要专门的机制(IPC)")能力实现过程间通信.

这恰好是线程的长处, 如果是同一个过程的不同线程, 它们在一个过程的地址空间里,所以, 其互相通信比拟不便, 它们之间的切换也比较简单. (创立线程比较简单, 切换也比拟笨重, 通信也比拟不便, 相互协作比拟好).

但多线程也有毛病,就是不稳固.因为同一个过程里的若干个线程,如果有一个(线程)解体, 就会使得整个过程的其余线程也一起解体, 互相烦扰比拟大. (互相通信比拟容易,互相烦扰也比拟大)

那软件设计时,个别采纳多过程模型还是多线程模型呢? 要看具体的利用场景, 比方对于浏览器软件, (浏览器的每一个选项卡, 或说每一个浏览器页面, 是用多线程还是多过程实现更好呢?) 显然是多过程,为什么呢, 因为浏览器页面之间简直没什么通信需要, 所以这时候线程易于通信的长处就施展不进去, 反而是一个线程解体,导致同过程其余线程解体这个毛病十分致命. (必定不心愿一个页面解体,会连带导致其余页面也解体) . 所以咱们个别是用多过程来实现浏览器的 ,实际上是拜访同一个网站的若干页面是在一个过程的不同线程(如关上了三个新浪的新闻页,这三个页面对应一个过程), 但拜访不同的网站是不同的过程(如关上了两个新浪,三个搜狐,一个网易,对应三个过程)



因为晚期Linux对线程反对不好,导致很多软件的Linux版本大多是多过程模型,如Oracle和Postgre.而Windows晚期对线程绝对就反对较好,故而某些软件的Win版本,大多采纳多线程模型. 当初Linux提供了多线程反对,一般来说多线程模型更多一些.

本文由mdnice多平台公布