关于后端:多进程与多线程

2次阅读

共计 1664 个字符,预计需要花费 5 分钟才能阅读完成。

Golang

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

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

用代码验证:


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 抉择单线程模型

redis 网络 IO 模型


mysql 服务端和 postgresql 服务端

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

如下:

所以 mysql 有线程池的说法。

而对于 pg:


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

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

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

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

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

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


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

本文由 mdnice 多平台公布

正文完
 0