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多平台公布