你對swoole的程序,執行緒知道多少

2020-11-24 18:00:33

欄目介紹swoole的程序,執行緒。

推薦(免費):
程序

1、程序之間不共用任何狀態
2、程序的排程由作業系統完成
3、每個程序都有自己獨立的記憶體空間
4、程序間通訊主要是通過訊號傳遞的方式來實現的,實現方式有多種,號誌、管道、事件等,任何一種方式的通訊效率都需要過核心,導致通訊效率比較低
5、由於是獨立的記憶體空間,上下文切換的時候需要儲存先呼叫棧的資訊、cpu各暫存器的資訊、虛擬記憶體、以及開啟的相關控制程式碼等資訊,所以導致上下文程序間切換開銷很大,通訊麻煩。

執行緒

1、執行緒之間共用變數,解決了通訊麻煩的問題對於變數的存取需要鎖
2、一個程序可以擁有多個執行緒,但是其中每個執行緒會共用父程序像作業系統申請資源,這個包括虛擬記憶體、檔案等,由於是共用資源,所以建立執行緒所需要的系統資源佔用比程序小很多,相應的可建立的執行緒數量也變得相對多很多。
3、另外在排程方面也是由於記憶體是共用的,所以上下文切換的時候需要儲存的東西就像對少一些,這樣一來上下文的切換也變得高效。

解釋
  • 通過php,執行一個php檔案,這個時候就相當於我們建立了一個程序,這個程序會在系統中駐存,申請屬於它自己的記憶體空間系統資源並且執行相應的程式。
    在這裡插入圖片描述
swoole程序

在這裡插入圖片描述
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程序當中投遞過來。

client跟server的互動:

1、client請求到達 Main Reactor,Client實際上是與Master程序中的某個Reactor執行緒發生了連線。

2、Main Reactor根據Reactor的情況,將請求註冊給對應的Reactor (每個Reactor都有epoll。用來監聽使用者端的變化)

3、使用者端有變化時Reactor將資料交給worker來處理

4、worker處理完畢,通過程序間通訊(比如管道、共用記憶體、訊息佇列)發給對應的reactor。

5、reactor將響應結果發給相應的連線請求處理完成

Master程序內的回撥函數
  • onStart Server啟動在主程序的主執行緒回撥此函數
  • onShutdown 此事件在Server正常結束時發生
Manager程序內的回撥函數
  • onManagerStart 當管理程序啟動時呼叫它
  • onManagerStop 當管理程序結束時呼叫它
  • onWorkerError 當worker/task_worker程序發生異常後會在Manager程序內回撥此函數
Worker程序內的回撥函數
  • onWorkerStart 此事件在Worker程序/Task程序啟動時發生
  • onWorkerStop 此事件在worker程序終止時發生。
  • onConnect 有新的連線進入時,在worker程序中回撥
  • onClose TCP使用者端連線關閉後,在worker程序中回撥此函數
  • onReceive 接收到資料時回撥此函數,發生在worker程序中
  • onPacket 接收到UDP封包時回撥此函數,發生在worker程序中
  • onFinish 當worker程序投遞的任務在task_worker中完成時,task程序會通過finish()方法將任務處理的結果傳送給worker程序。
  • onWorkerExit 僅在開啟reload_async特性後有效。非同步重新啟動特性
  • onPipeMessage 當工作程序收到由 sendMessage 傳送的管道訊息時會觸發事件
Task程序內的回撥函數
  • 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';
程序

1、程序之間不共用任何狀態
2、程序的排程由作業系統完成
3、每個程序都有自己獨立的記憶體空間
4、程序間通訊主要是通過訊號傳遞的方式來實現的,實現方式有多種,號誌、管道、事件等,任何一種方式的通訊效率都需要過核心,導致通訊效率比較低
5、由於是獨立的記憶體空間,上下文切換的時候需要儲存先呼叫棧的資訊、cpu各暫存器的資訊、虛擬記憶體、以及開啟的相關控制程式碼等資訊,所以導致上下文程序間切換開銷很大,通訊麻煩。

執行緒

1、執行緒之間共用變數,解決了通訊麻煩的問題對於變數的存取需要鎖
2、一個程序可以擁有多個執行緒,但是其中每個執行緒會共用父程序像作業系統申請資源,這個包括虛擬記憶體、檔案等,由於是共用資源,所以建立執行緒所需要的系統資源佔用比程序小很多,相應的可建立的執行緒數量也變得相對多很多。
3、另外在排程方面也是由於記憶體是共用的,所以上下文切換的時候需要儲存的東西就像對少一些,這樣一來上下文的切換也變得高效。

解釋
  • 通過php,執行一個php檔案,這個時候就相當於我們建立了一個程序,這個程序會在系統中駐存,申請屬於它自己的記憶體空間系統資源並且執行相應的程式。
    在這裡插入圖片描述
swoole程序

在這裡插入圖片描述
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程序當中投遞過來。

client跟server的互動:

1、client請求到達 Main Reactor,Client實際上是與Master程序中的某個Reactor執行緒發生了連線。

2、Main Reactor根據Reactor的情況,將請求註冊給對應的Reactor (每個Reactor都有epoll。用來監聽使用者端的變化)

3、使用者端有變化時Reactor將資料交給worker來處理

4、worker處理完畢,通過程序間通訊(比如管道、共用記憶體、訊息佇列)發給對應的reactor。

5、reactor將響應結果發給相應的連線請求處理完成

Master程序內的回撥函數
  • onStart Server啟動在主程序的主執行緒回撥此函數
  • onShutdown 此事件在Server正常結束時發生
Manager程序內的回撥函數
  • onManagerStart 當管理程序啟動時呼叫它
  • onManagerStop 當管理程序結束時呼叫它
  • onWorkerError 當worker/task_worker程序發生異常後會在Manager程序內回撥此函數
Worker程序內的回撥函數
  • onWorkerStart 此事件在Worker程序/Task程序啟動時發生
  • onWorkerStop 此事件在worker程序終止時發生。
  • onConnect 有新的連線進入時,在worker程序中回撥
  • onClose TCP使用者端連線關閉後,在worker程序中回撥此函數
  • onReceive 接收到資料時回撥此函數,發生在worker程序中
  • onPacket 接收到UDP封包時回撥此函數,發生在worker程序中
  • onFinish 當worker程序投遞的任務在task_worker中完成時,task程序會通過finish()方法將任務處理的結果傳送給worker程序。
  • onWorkerExit 僅在開啟reload_async特性後有效。非同步重新啟動特性
  • onPipeMessage 當工作程序收到由 sendMessage 傳送的管道訊息時會觸發事件
Task程序內的回撥函數
  • 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的程序,執行緒知道多少的詳細內容,更多請關注TW511.COM其它相關文章!