首頁  >  文章  >  後端開發  >  PHP執行緒進程和並發實例詳解

PHP執行緒進程和並發實例詳解

小云云
小云云原創
2018-03-08 09:36:281476瀏覽


進程

進程是什麼?行程是正在執行的程式;行程是正在電腦上執行的程式實例;行程是能分配給處理器並由處理器執行的實體。 行程一般會包含指令集和系統資源集,這裡的指令集是指程式碼,這裡的系統資源集是指I/O、CPU、記憶體等。 綜合起來,我們也可以理解進程是具有一定獨立功能的程式在關於某個資料集合上的一次運行活動, 進程是系統進行資源分配和調度的一個獨立單位。

在進程執行時,進程都可以被唯一的表示,由以下一些元素組成:

  • 進程描述符:進程的唯一標識符,用來和其它進程區分。在Linux中叫進程ID,在系統呼叫fork期間生成,只是我們透過getpid返回的不是其pid字段,而是其線程組號tgid。 

  • 行程狀態:我們常說的掛起、執行等狀態,其表示的是目前的狀態。 

  • 優先權:進程間的執行調度相關,相對於其它進程而言。 

  • 程式計數器:程式中即將被執行的下一指令的位址,該位址是核心術中或使用者記憶體空間中的記憶體位址。 

  • 記憶體指標:包含程式碼和行程相關資料的指針,還有和其它程序共享記憶體區塊的指標。 

  • 上下文資料:進程執行時處理器的暫存器的資料。

  • I/O狀態資訊:包含明確的I/O請求、指派給行程的I/O裝置等 

  • 記賬資訊:可能包含處理器時間總和、使用的時脈數總和、時間限制等

#以上的這些元素都會放在一個叫做行程控制區塊的資料結構中。進程控制塊是作業系統能夠支援多進程和提供多處理的結構。 當作業系統做進程切換時,它會執行兩步驟操作,一是中斷目前處理器中的進程,二是執行下一個進程。 不管是中斷還是執行,進程控制區塊中的程式計數器、上下文資料和進程狀態都會改變。 當進程中斷時,作業系統會把程式計數器和處理器暫存器(對應進程控制塊中的上下文資料)保存到進程控制塊中的對應位置, 進程狀態也會有所變化,可能進入阻塞狀態,也有可能進入就緒態。 執行下一個行程時,作業系統會依照規則將下一個行程設定為運行態,並載入即將要執行進程的程式上下文資料和程式計數器等。

執行緒

行程有兩個特性部分:資源所有權和排程執行。 資源所有權是指進程包含了進程運行所需的記憶體空間、I/O等資源。 調度執行是指進程執行過程中間的執行路徑,或說程式的指令執行流。 這兩個特性部分是可以分開的,分開後,擁有資料所有權的通常稱為進程,擁有執行程式碼的可分派部分的稱為線程或輕量級進程。

執行緒有「執行的線索」的意思在裡面,而進程在多執行緒環境中被定義為資源擁有者,其還是會儲存進程的進程控制塊。 執行緒的結構與行程不同,每個執行緒包含:

  • #執行緒狀態: 執行緒目前的狀態。 

  • 一個執行堆疊 

  • # 私有的資料區: 每個執行緒局部變數的靜態儲存空間 

  • 暫存器集: 儲存處理器的一些狀態

每個行程都有一個行程控制區塊和使用者位址空間,每個執行緒都有一個獨立的堆疊和獨立的控制塊,都有自己一個獨立執行上下文。 其結構如圖8.1所示。

PHP執行緒進程和並發實例詳解

圖8.1 進程模型圖

執行緒在執行過程中與進程有一些不同。每個獨立的執行緒都有一個程式運行的入口、順序執行序列和程式的出口。 但是執行緒不能夠獨立執行,必須依存在於進程之中,由行程提供多個執行緒執行控制。 從邏輯角度來看,多執行緒的意義在於一個行程中,有多個執行部分可以同時執行。 此時,進程本身不是基本運行單位,而是執行緒的容器。

線程較之進程,其優勢在於一個快,不管是創建新的線程還是終止一個線程;不管是線程間的切換還是線程間共享資料或通信,其速度與進程相比都有較大的優勢。


並發及並行

並發又稱共行,是指能處理多個同時性活動的能力,並發事件之間不一定要同一時刻發生。 例如,現代電腦系統可在同一段時間內以進程的形式將多個程式載入到記憶體中,並藉由處理器的時分複用, 以在一個處理器上表現出同時運作的感覺。

並行是指同時發生的兩個並發事件,具有並發的含義,而並發則不一定並行。

並發和並行的差異就是一個處理器同時處理多個任務和多個處理器或是多核心的處理器同時處理多個不同的任務。 前者是邏輯上的同時發生(simultaneous),而後者是物理上的同時發生。

PHP的各種並發模型

既然有兩個模型,那麼PHP使用的是哪一個呢?答案是都支持,也就是說PHP支持多執行緒的模型, 在多執行緒情況下通常要解決資源共享和隔離的問題。 PHP本身是線程安全的。

具體來說是那種模型需要看使用的是哪個SAPI,比如說在Apache中,那麼就可能使用多執行緒模型, 也可能使用多進程模型。而php-fpm使用的就是多進程模型。

目前比較推薦的方式是使用php-fpm的模型,因為這個模型對PHP來說有許多的優點:

  1. ##記憶體釋放簡單,使用多進程模型時進程可以容易透過退出的方式來釋放內存, 由於PHP有非常多的擴展,稍有不慎就可能導致內存洩露,fpm通過進程退出方式簡單除暴的解決了問題。 

  2. 容災能力強,同樣的問題,擴充或php可能會出現段錯誤,如果是單一行程多執行緒模型, 那麼整個PHP就掛掉了。這會影響服務,多進程的話,某個進程死掉了也不會影響整體的服務。

多行程有多行程的優勢,多執行緒也有多執行緒的優勢,例如HHVM它選擇的是多執行緒模型。 多執行緒模型最大的好處是資訊共享和通訊方便,因為在同一個進程空間內,可以直接使用指標。

例如opcode cache工具,在PHP裡,apc以及opcache等等使用的是共享內存來共享opcode, 那麼在HHVM中則不需要走共享內存,共享內存還有個問題是存儲複雜的資料結構不方便, 因為指標的問題,多執行緒情況下C/C++中的資料結構是可以共享的。這對效率提升也是有幫助的。

多進程和多執行緒還有一個明顯的模型差異:在處理請求時的邏輯。

在多進程情況下,由於跨進程是不好傳遞fd連線的。那麼多行程通常會採用在父行程中listen(), 然後各個子程序accept()的方式來實作負載平衡。這樣的模型下可能會有驚群的問題。

而多執行緒模型下,可以採用一個獨立執行緒接受請求然後派發到各個worker執行緒的方式。

相關推薦:

單執行緒JS執行問題詳解

#PHP對多執行緒程式設計的支援以及使用

實作php多執行緒類別的案例

以上是PHP執行緒進程和並發實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn