1、進程之間不共享任何狀態
2、進程的調度由作業系統完成
3、每個進程都有自己獨立的記憶體空間
4、進程間通訊主要是透過訊號傳遞的方式來實現的,實現方式有多種,信號量、管道、事件等,任何一種方式的通訊效率都需要過內核,導致通訊效率比較低
5、由於是獨立的內存空間,上下文切換的時候需要保存先調用棧的信息、cpu各暫存器的資訊、虛擬記憶體、以及開啟的相關句柄等訊息,所以導致上下文進程間切換開銷很大,通訊麻煩。
1、線程之間共享變量,解決了通訊麻煩的問題對於變量的訪問需要鎖定
2、一個進程可以擁有多個線程,但是其中每個執行緒會共享父進程像作業系統申請資源,這包括虛擬記憶體、檔案等,由於是共享資源,所以創建執行緒所需的系統資源佔用比進程小很多,對應的可建立的執行緒數量也變得相對多很多。
3.另外在調度方面也是由於記憶體是共享的,所以上下文切換的時候需要保存的東西就像對少一些,這樣一來上下文的切換也變得高效。
1、Master行程:主程式
2、Manger行程:管理程式
3 、Worker進程:工作進程
4、Task進程:非同步任務工作進程
第一層,Master進程,這個是swoole的主進程,這個進程是用來處理swoole的核心事件驅動的,那麼在這個進程當中可以看到它擁有一個MainReactor[線程]以及若干個Reactor[線程],swoole所有對於事件的監聽都會在這些線程中實現,比如來自客戶端的連接,信號處理等。
1.1、MainReactor(主執行緒)
主執行緒會負責監聽server socket,如果有新的連線accept,主執行緒會評估每個Reactor執行緒的連線數量。將此連線分配給連線數最少的reactor線程,做一個負載平衡。
1.2 、Reactor執行緒群組
Reactor執行緒負責維護客戶端機器的TCP連線、處理網路IO、收發資料完全是異步非阻塞的模式。
swoole的主線程在Accept新的連接後,會將這個連接分配給一個固定的Reactor線程,在socket可讀時讀取數據,並進行協議解析,將請求投遞到Worker進程。在socket可寫入時將資料傳送給TCP客戶端。
1.3、心跳包偵測執行緒(HeartbeatCheck)
Swoole配置了心跳偵測之後,心跳包執行緒會在固定時間內對所有先前線上的連線
傳送偵測封包
1.4、UDP收包執行緒(UdpRecv)
接收並且處理客戶端udp封包
swoole想要實現最好的效能必須創建出多個工作進程幫助處理任務,但Worker進程就必須fork操作,但是fork操作是不安全的,如果沒有管理會出現很多的殭屍進程,進而影響伺服器效能,同時worker進程被誤殺或因為程式的原因會異常退出,為了確保服務的穩定性,需要重新建立worker流程。
Swoole在運行時會建立一個單獨的管理進程,所有的worker進程和task進程都是從管理進程Fork出來的。管理進程會監視所有子進程的退出事件,當worker進程發生致命錯誤或執行生命週期結束時,管理進程會回收此進程,並建立新的進程。換句話說,對於worker、task進程的建立、回收等操作全權有「保姆」Manager進程進行管理
worker 進程屬於swoole的主邏輯進程,使用者處理客戶端的一系列請求,接受由Reactor線程投遞的請求資料包,並執行PHP回呼函數處理資料產生回應資料並發給Reactor執行緒,由Reactor線程發送給TCP客戶端可以是異步非阻塞模式,也可以是同步阻塞模式
taskWorker進程這一進城是swoole提供的非同步工作進程,這些進程主要用於處理一些耗時較長的同步任務,在worker進程中投遞過來。
1、client要求到達 Main Reactor,Client其實是與Master行程中的某個Reactor執行緒發生了連線。
2、Main Reactor根據Reactor的情況,將請求註冊給對應的Reactor (每個Reactor都有epoll。用來監聽客戶端的變化)
3、客戶端有變化時Reactor將資料交給worker來處理
4、worker處理完畢,透過進程間通訊(例如管道、共享記憶體、訊息佇列)發給對應的reactor。
5、reactor將回應結果發給對應的連線請求處理完成
<?php //tcp协议$server=new Swoole\Server("0.0.0.0",9800); //创建server对象$server->set([ 'worker_num'=>3, //设置进程 //'heartbeat_idle_time'=>10,//连接最大的空闲时间 //'heartbeat_check_interval'=>3 //服务器定时检查 'open_length_check'=>1, 'package_length_type'=>'N',//设置包头的长度 'package_length_offset'=>0, //包长度从哪里开始计算 'package_body_offset'=>4, //包体从第几个字节开始计算 'package_max_length'=>1024 * 1024 * 2,]);$server->on("Start",function (){ var_dump(1); //设置主进程的名称 swoole_set_process_name("server-process:master");});//服务关闭时候触发(信号)$server->on("shutdown",function (){});//当管理进程启动时调用它$server->on('ManagerStart',function (){ var_dump(2); //swoole_set_process_name("server-process:manger");});$server->on('WorkerStart',function ($server,$workerId){ // swoole_set_process_name("server-process:worker"); var_dump(3);});//监听事件,连接事件(woker进程当中)$server->on('connect',function ($server,$fd){ echo "新的连接进入:{$fd}".PHP_EOL;});//消息发送过来(woker进程当中)$server->on('receive',function (swoole_server $server, int $fd, int $reactor_id, string $data){ //var_dump("消息发送过来:".$data); //服务端});//消息关闭$server->on('close',function (){ echo "消息关闭".PHP_EOL;});//服务器开启$server->start();echo '123456';
1、進程之間不共用任何狀態
2、行程的調度由作業系統完成
3、每個行程都有自己獨立的記憶體空間
4、進程間通訊主要是透過訊號傳遞的方式來實現的,實作方式有多種,訊號量、管道、事件等,任何一種方式的通訊效率都需要過內核,導致通訊效率比較低
5、由於是獨立的內存空間,上下文切換的時候需要保存先調用棧的信息、cpu各寄存器的信息、虛擬內存、以及打開的相關句柄等訊息,所以導致上下文進程間切換開銷很大,通訊麻煩。
1、線程之間共享變量,解決了通訊麻煩的問題對於變量的訪問需要鎖定
# 2、一個進程可以擁有多個線程,但是其中每個線程會共享父進程像作業系統申請資源,這個包括虛擬記憶體、檔案等,由於是共享資源,所以創建線程所需要的系統資源佔用比進程小得多,相應的可創建的線程數量也變得相對多得多。
3.另外在調度方面也是由於記憶體是共享的,所以上下文切換的時候需要保存的東西就像對少一些,這樣一來上下文的切換也變得高效。
1、Master行程:主程式
2、Manger行程:管理程式
3 、Worker進程:工作進程
4、Task進程:非同步任務工作進程
第一層,Master進程,這個是swoole的主進程,這個進程是用來處理swoole的核心事件驅動的,那麼在這個進程當中可以看到它擁有一個MainReactor[線程]以及若干個Reactor[線程],swoole所有對於事件的監聽都會在這些線程中實現,比如來自客戶端的連接,信號處理等。
1.1、MainReactor(主執行緒)
主執行緒會負責監聽server socket,如果有新的連線accept,主執行緒會評估每個Reactor執行緒的連線數量。將此連線分配給連線數最少的reactor線程,做一個負載平衡。
1.2 、Reactor執行緒群組
Reactor執行緒負責維護客戶端機器的TCP連線、處理網路IO、收發資料完全是異步非阻塞的模式。
swoole的主線程在Accept新的連接後,會將這個連接分配給一個固定的Reactor線程,在socket可讀時讀取數據,並進行協議解析,將請求投遞到Worker進程。在socket可寫入時將資料傳送給TCP客戶端。
1.3、心跳包偵測執行緒(HeartbeatCheck)
Swoole配置了心跳偵測之後,心跳包執行緒會在固定時間內對所有先前線上的連線
傳送偵測封包
1.4、UDP收包執行緒(UdpRecv)
接收並且處理客戶端udp封包
swoole想要實現最好的效能必須創建出多個工作進程幫助處理任務,但Worker進程就必須fork操作,但是fork操作是不安全的,如果沒有管理會出現很多的殭屍進程,進而影響伺服器效能,同時worker進程被誤殺或因為程式的原因會異常退出,為了確保服務的穩定性,需要重新建立worker流程。
Swoole在運行時會建立一個單獨的管理進程,所有的worker進程和task進程都是從管理進程Fork出來的。管理進程會監視所有子進程的退出事件,當worker進程發生致命錯誤或執行生命週期結束時,管理進程會回收此進程,並建立新的進程。換句話說,對於worker、task進程的創建、回收等操作全權有「保姆」Manager進程進行管理
worker 進程屬於swoole的主邏輯進程,用戶處理客戶端的一系列請求,接受由Reactor線程投遞的請求資料包,並執行PHP回呼函數處理資料產生回應資料並發給Reactor線程,由Reactor線程傳送給TCP客戶端可以是非同步非阻塞模式,也可以是同步阻塞模式
taskWorker進程這一進城是swoole提供的非同步工作進程,這些進程主要用於處理一些耗時較長的同步任務,在worker進程中投遞過來。
1、client要求到達 Main Reactor,Client其實是與Master行程中的某個Reactor執行緒發生了連線。
2、Main Reactor根據Reactor的情況,將請求註冊給對應的Reactor (每個Reactor都有epoll。用來監聽客戶端的變化)
3、客戶端有變化時Reactor將資料交給worker來處理
4、worker處理完畢,透過進程間通訊(例如管道、共享記憶體、訊息佇列)發給對應的reactor。
5、reactor將回應結果發給對應的連線請求處理完成
##onTask在task_worker進程內被呼叫。 worker程序可以使用swoole_server_task函數向task_worker程序投遞新的任務
###onWorkerStart 此事件在Worker程序/Task程序啟動時發生######onPipeMessage 當工作程序收到由sendMessage 傳送的管道訊息時會觸發事件#########簡單說明:#########1、伺服器關閉程式終止時最後一次事件是onShutdown。 ######2、伺服器啟動成功後,onStart/onManagerStart/onWorkerStart會在不同的進程內並發執行,並不是順序的。 ######3、所有事件回呼均在$server->start後發生,start之後寫的程式碼是無效程式碼。 ######4、onStart/onManagerStart/onWorkerStart 3個事件的執行順序是不確定的#########swoole執行流程圖###########<?php //tcp协议$server=new Swoole\Server("0.0.0.0",9800); //创建server对象$server->set([ 'worker_num'=>3, //设置进程 //'heartbeat_idle_time'=>10,//连接最大的空闲时间 //'heartbeat_check_interval'=>3 //服务器定时检查 'open_length_check'=>1, 'package_length_type'=>'N',//设置包头的长度 'package_length_offset'=>0, //包长度从哪里开始计算 'package_body_offset'=>4, //包体从第几个字节开始计算 'package_max_length'=>1024 * 1024 * 2,]);$server->on("Start",function (){ var_dump(1); //设置主进程的名称 swoole_set_process_name("server-process:master");});//服务关闭时候触发(信号)$server->on("shutdown",function (){});//当管理进程启动时调用它$server->on('ManagerStart',function (){ var_dump(2); //swoole_set_process_name("server-process:manger");});$server->on('WorkerStart',function ($server,$workerId){ // swoole_set_process_name("server-process:worker"); var_dump(3);});//监听事件,连接事件(woker进程当中)$server->on('connect',function ($server,$fd){ echo "新的连接进入:{$fd}".PHP_EOL;});//消息发送过来(woker进程当中)$server->on('receive',function (swoole_server $server, int $fd, int $reactor_id, string $data){ //var_dump("消息发送过来:".$data); //服务端});//消息关闭$server->on('close',function (){ echo "消息关闭".PHP_EOL;});//服务器开启$server->start();echo '123456';
以上是你對swoole的進程,線程知道多少的詳細內容。更多資訊請關注PHP中文網其他相關文章!