进程
进程和线程,涉及到操作系统的基本知识,但是很多phper不懂,这是实话,因为php简单易学,大部分人在零基础学php编程的时候都没有去了解过这个东西。
既然关系到操作系统,那跟我们学swoole又有什么关系?
这关系可大了去了。如果说这两个概念都搞不清除的话,对于swoole,你能学会几乎可以说是天方夜谭了。
对于操作系统而言,进程就是一个任务,比方说你打开了一个记事本,那就启动了一个进程,打开了两个浏览器,就是另外开启了两个进程,再或者说我现在在word内写文章,打开word也会占用一个进程。也就是说,一个进程至少要干一件事情。
对于linux系统而言,如果你想要查看当前系统中运行着哪些进程,可以通过ps命令进行查看。
比如我现在打开一个终端,用vim打开一个文件
1 | vim a.php |
打开后这个终端不动,再新打开一个终端,执行ps命令后
1 | ps aux | grep vim |
可以看到,有两个vim相关的进程在我执行ps的那一霎那还在执行。至于ps命令的结果那一堆都是什么意思,没有linux基础的可以回去补补了,这里只需要关注有两个在执行的进程即可。
线程
有些情况下,一个进程会同时做一些事情,比如说word。它可以同时进行打字、拼写检查等操作。注意这里我们说的同时进行。像这样,在一个进程内部,同时运行着多个“子任务”,我们就可以把这些子任务称之为“线程”。即进程是由多个线程组成的,一个进程至少要有一个线程。实际上,线程是操作系统最小的执行单元。
多任务的实现
试想一下,如果我们要同时执行多个任务怎么办?
根据上文的理解,我们可以
启动多个进程
启动一个进程,并在该进程内启动多个线程
启动多个进程,每个进程内启动多个线程
多进程的实现
有同学要嚷嚷了,这上面说的都是概念性东西,一来抽象,二来怎么玩呢?想动手试试。先不要着急,这就跟我们学习一门新语言一样,心急,基础打不牢,后面问题才会更多!
我们举一个实际点的例子:各位熟悉的apache,其实就是一种多进程实现的案例。当父进程监听到有新的请求时,就会fork出新的子进程来对之进行处理。
Linux的fork()函数通过系统调用即可实现创建一个与原进程几乎相同的进程。对于多任务,通常我们会设计Master-Worker模式,即一个Master进程负责分配任务,多个Worker进程负责执行任务。同理,如果是多线程,Master就是主线程,Worker就是子线程。
多进程与多线程的区别
多进程的优点就是稳定性很高,如果一个进程挂了,不会影响其他子进程,当然,如果主进程挂了那就都玩完(主进程挂点的可能性微乎其微,后面讲进程模型会说到)。而对于多线程,这个恐怕就是致命的缺点了,因为所有线程共享内存,如果某一个线程挂了,那这个进程几乎就崩溃了。
性能方面,不论是进程还是线程,如果启动太多,无疑都会带来CPU的调度问题,因为进程或者线程的切换,本身就非常耗费资源。数量达到一定程度的时候,CPU和内存就消耗殆尽,电脑就死机了。
举一个例子:使用过windows的用户都知道,如果我们打开的软件越多(开启的进程也就越多),电脑就会越卡,甚至装死机没反应。
线程与进程相比,自然是要比进程更轻量一些,而且线程之间是共享内存的,所以不同线程之间的交互就显得容易实现。而对于多进程之间的通信,需要借助消息队列,共享内存等复杂的方式才可以实现。
进程和线程看明白是怎么回事了吗?不明白还请多看几遍,明白后思考一下下面的问题
php、nginx、apache各自跟线程和进程是什么关系