# 進程
在人類剛發明計算機的時候,只能同時處理一件事情。我們通常說程序的設計來自于現實的人類世界,這個進程同樣也是。

<center>圖:1.3-1</center>
圖1.3-1是早期計算機的多程序執行流程,我們可以看到在一個CPU的生命周期里面,多個程序是順序執行的。后面的程序什么時候執行取決于前面的程序什么之后執行完。如果當前執行的程序進行IO時,CPU也只能等待,CPU的使用率極低。如果當前執行的程序占用CPU時間很長,其他程序得不到CPU的執行權,只能卡著不動。

<center>圖:1.3-2</center>
基于上面說的單進程有很多的缺點,所以出現了多道程序技術,使得程序可以并發執行。從上圖可以看出來多道程序設計把CPU分成了時間片,可以在單CPU的情況下實現并發。CPU以人無法感知的速度在不停切換執行不同的程序,這樣讓我們看起來像是多個程序同時在執行。

<center>圖:1.3-3</center>
從圖1.3-3我們可以看到了每個進程有自己獨立的內存、地址空間、數據棧等等,每個進程都跟其他進程互不干擾,這就是為什么有些人在寫代碼都時候,說定義了一個全局的屬性,但是一個進程改變了,另一個進程讀取卻沒有變化,這就是原因,每個進程有自己的獨立堆棧,內存資源等。
### 進程狀態

<center>圖:1.3-4</center>
在圖1.3-4里面可以看到進程有不同的狀態,當進程在不同狀態進程處于就緒態的時候就是等待操作系統進行調度。前面我們提到過進程的切換,CPU不斷的切換到不同的進程來執行,當CPU調度別的進程當前執行的進程怎么辦呢?下次再調度會這個進程的之后怎么知道代碼執行到哪里,都有什么數據呢?其實當CPU調度別的進程的時候,會保存當前執行進程的信息、狀態,這種操作叫做上下文切換。一個進程從運行態轉到休眠狀態的時候,進程的現場會保存到該進程的內核棧,當這進程再次進入就運行狀態的時候,CPU從這個進程的PCB內核棧讀取這個現場信息恢復進程。

<center>圖:1.3-5</center>
多道程序設計把CPU執行的時間分割成了很小的時間片,由操作系統在不同狀態的進程進行調度。但是在一個核心CPU一次只能處理一件事情,只是因為每次切換的時間太快了,讓我們認為是一起執行的。
### 上下文切換

<center>圖:1.3-6</center>
當一個進程遇到阻塞的之后CPU就會切換到另一個進程執行,避免在在進程阻塞的時候浪費CPU資源。
> 進程不是越多越好,進程過多在上下文切換過程中浪費大量的CPU可執行時間
> 并發與并行的區別:并發是某一個時間段做多少事情,并行是同一時刻同時做多件事情
### 孤兒進程
前面說過了,計算機模擬的是人類世界,那么這個孤兒進程跟我們人類世界一樣,沒有父母沒有監護人的為孤兒。孤兒進程產生的原因是父進程終止執行了,但是子進程依然在執行的子進程就被叫做孤兒進程。
### 僵尸進程
僵尸進程產生的原因是因為子進程終止之后父進程沒有對其進行回收,子進程的進程描述符依然保留在系統當中,所以產生了僵尸進程,僵尸進程對于操作系統是有資源浪費的。所以務必避免出現僵尸進程,解決辦法可以在父進程調用wait或者waitpid解決。
### 守護進程
在Linux操作系統里面我們想要實現關閉終端之后還可以運行,我們通常采用
* nohup
* setsid
* 命令后面加 &
這幾種方式,我們想想在前面說過的孤兒進程好像就可以是現在這樣的功能。我們只要父進程退出執行,子進程還是依然會執行的。這就是我們通過故意產生孤兒進程來實現守護進程的功能。
- 第一章:基礎知識
- 課程簡介
- PHP-FPM過渡常駐內存
- 進程
- 實戰:實現Master-Worker
- 線程
- 實戰:CC攻擊器
- 協程
- 實戰:實現waitGroup功能
- 進程、線程、協程的區別
- 第二章:初識Swoft2.0
- Swoft介紹
- Swoft環境安裝
- gcc升級
- 安裝Swoft框架
- 目錄結構介紹
- SwoftCli工具
- Swoft配置
- 第三章:Swoft2.0核心
- 上下文
- 常駐內存沒有上下文隔離
- 實戰:手寫swoole框架上下文管理
- Bean容器
- 實戰:根據容器原理實現容器
- 實戰:通過容器實現依賴注入
- Bean容器定義與使用
- 配置文件定義Bean
- 容器類型
- 面向接口的容器
- 注解
- 實戰:實現注解
- 自定義Swoft注解類
- 事件
- 連接池
- 實戰:Swoole實現連接池
- 第四章:Http服務器
- Http Server生命周期
- Http Server配置
- 控制器
- 路由
- 請求對象Request
- 響應對象Response
- Http異常處理
- 中間件
- 實戰:中間件實現JWT登陸授權
- 第五章:驗證器
- 內置驗證類型
- 驗證器的使用
- 自定義驗證器
- 第六章:數據庫操作
- 連接數據庫
- 實體模型
- 模型事件
- 查詢器
- 事務處理
- 連接池配置
- 讀寫分離
- 多數據庫切換
- Models分層結構
- 實戰:實現用戶CURD API
- 第七章:Redis
- 連接redis和使用
- Redis連接池
- Redis集群配置(單機版)
- Redis集群配置(多服務器)
- Redis連接集群
- Redis實戰:實現延時任務
- 第八章:AOP編程
- AOP概念
- AOP實現原理
- 實戰實現AOP:靜態代理
- 實戰實現AOP:動態代理
- 切面注解介紹
- PointExecution切面
- PointBean切面
- PointAnnotation切面
- 實戰:使用AOP實現日志記錄
- 第九章:任務處理
- 進程使用
- 進程池使用
- 實戰:進程消費隊列
- 實戰:進程實現RabbitMQ延時隊列
- 異步任務
- 協程任務
- 定時任務