一 概念
- 進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。每個進程都有自己的獨立內存空間,不同進程通過進程間通信來通信。由於進程比較重量,占據獨立的內存,所以上下文進程間的切換開銷(棧、寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。
- 線程是指進程內的一個執行單元,也是進程內的可調度實體。線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內存,上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據。
- 協程是一種用戶態的輕量級線程,協程的調度完全由用戶控制。從技術的角度來說,“協程就是你可以暫停執行的函數”。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。
二 協程與線程的區別
- 一個線程可以多個協程,一個進程也可以單獨擁有多個協程。
- 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態。
- 線程是搶占式,而協程是非搶占式的,所以需要用戶自己釋放使用權來切換到其他協程,因此同一時間其實只有一個協程擁有運行權,相當於單線程的能力。
- 協程並不是取代線程, 而且抽象於線程之上, 線程是被分割的CPU資源, 協程是組織好的代碼流程, 協程需要線程來承載運行, 線程是協程的資源, 但協程不會直接使用線程, 協程直接利用的是執行器(Interceptor), 執行器可以關聯任意線程或線程池, 可以使當前線程, UI線程, 或新建新程.。
- 線程是協程的資源。協程通過Interceptor來間接使用線程這個資源
三 PHP7.2協程改動
四 SWOOLE中協程數量
五 當前項目的數據庫連接池的協程channel
- 通道與
PHP
的Array
類似,僅占用內存,沒有其他額外的資源申請,所有操作均為內存操作,無IO
消耗 - 底層使用
PHP
引用計數實現,無內存拷貝。即使是傳遞巨大字符串或數組也不會產生額外性能消耗 - swoole中channel與go的區別是,增加了最大讀取時間參數,當超過此事件未得到消費數據或者未能新增消費數據自動拋出異常