[TOC]
## 什么是進程、線程、協程
### 進程( Process)
是計算機中的程序關于某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎,進程是一個“執行中的程序
進程的三態模型:多道程序系統中,進程在處理器上交替運行,狀態不斷地發生變化
- 運行
運行:當一個進程在處理機上運行時,則稱該進程處于運行狀態。處于此狀態的進程的數目小于等于處理器的數目,對于單處理機系統,處于運行狀態的進程只有一個。在沒有其他進程可以執行時(如所有進程都在阻塞狀態),通常會自動執行系統的空閑進程。
- 就緒
就緒:當一個進程獲得了除處理機以外的一切所需資源,一旦得到處理機即可運行,則稱此進程處于就緒狀態。就緒進程可以按多個優先級來劃分隊列。例如,當一個進程由于時間片用完而進入就緒狀態時,排入低優先級隊列;當進程由I/O操作完成而進入就緒狀態時,排入高優先級隊列。
- 阻塞
阻塞:也稱為等待或睡眠狀態,一個進程正在等待某一事件發生(例如請求Io而等待I/o完成等)而暫時停止運行,這時即使把處理機分配給進程也無法運行,故稱該進程處于阻塞狀態。
進程的五態模型:對于一個實際的系統,進程的狀態及其轉換更為復雜
新建態、活躍就緒/靜止就緒、運行、活躍阻塞/靜止阻塞、終止態
### 線程
線程,有時被稱為輕量級進程 (Lightweight Process,LWP),是程序執行流的最小單元。
線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程自己不擁有系統資源,只擁有一點兒在運行中必不可少的資源但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。
一個線程可以刨建和撤消另一個線程,同一進程中的多個線程之間可以并發執行。
線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派cPU的基本單位指運行中的程序的調度單位。
在單個程序中同時運行多個線程完成不同的工作,稱為多線程。
每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。
線程的狀態:就緒、阻塞、運行
### 協程
協程是一種用戶態的輕量級線程,協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。
### 線程與進程的區別
1. 線程是進程內的一個執行單元,進程內至少有一個線程,它們共享進程的地址空間,而進程有自己獨立的地址空間
2. 進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
3. 線程是處理器調度的基本單位但進程不是
4. 二者均可并發執行
5. 每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口,但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制
### 線程與協程的區別
1. 一個線程可以多個協程,一個進程也可以單獨擁有多個協程
2. 線程進程都是同步機制,而協程則是異步
3. 協程能保留上一次調用時的狀態,每次過程重入時,就相當于進入上一次調用的狀態
## 什么是多進程、多線程
### 多進程
同一個時間里,同一個計算機系統中如果允許兩個或兩個以上的進程處于運行狀態,這就是多進程(如同時聽歌,玩游戲)
多開一個進程,多分配一份資源,進程間通訊不方便
### 多線程
線程就是把一個進程分為很多片,每一片都可以是一個獨立的流程
與多進程的區別是只會使用一個進程的資源,線程間可以直接通信
## 同步阻塞模型
### 多進程
最早的服務器端程序都是通過多進程、多線程來解決并發IO的問題一個請求創建一個進程,然后子進程進入循環同步堵塞地與客戶端連接進行交互,收發處理數據
### 多線程
用多線程模式實現非常簡單,線程中可以直接向某一個客戶端連接發送數據
### 缺點
這種模型嚴重依賴進程的數量解決并發問題
啟動大量進程會帶來額外的進程調度消耗
## 異步非阻塞模型
- 現在各種高并發異步IO的服務器程序都是基于epol!實現的
- Io復用異步非阻塞程序使用經典的 Reactor模型, Reactor顧名思義就是反應堆的意思,它本身不處理任何數據收發。只是可以監視一個 socket句柄的事件變化
Reactor有4個核心的操作
1. add添加 socket監聽到 reactor
2. set修改事件監聽,可以設置監聽的類型,如可讀、可寫
3. de從 reactor中移除,不再監聽事件
4. callback,事件發生后對應的處理邏輯,一般在add/set時制定
Nginx:多線程 Reactor
Swoole:多線程 Reactor+多進程 Worker
## PHP并發編程實踐
### PHP的 Swoole擴展
PHP的異步、并行、高性能網絡通信引擎,使用純C語言編寫,提供了PHP語言的異步多線程服務器,異步TcP/UDP網絡客戶端,異步 MYSQL,異步 Redis,數據庫連接池, Asynctask,消息隊列,毫秒定時器,異步文件讀寫,異步DNS查詢
除了異步Io的支持之外, Swoole為PHP多進程的模式設計了多個并發數據結構和IPC通信機制,可以大大簡化多進程并發編程的工作。
Swoole2.0支持了類似Go語言的協程,可以使用完全同步的代碼實現異步程序
Swoole的異步 MYSQL實現
```
$db = new Swoole\MYSQL;
$server = array('host'=>",'user=>'','password'=>",database=>",);
$db->connect($server, function(Sdb, Result){
$db->query ("show tables", function(Swoole\MYSQL $db, $result){
//do some thing
});
});
```