[轉載] PHP 線程,進程和併發

轉載自http://chenpeng.info/html/3021php

進程

進程是什麼?進程是正在執行的程序;進程是正在計算機上執行的程序實例;進程是能分配給處理器並由處理器執行的實體。 進程通常會包括指令集和系統資源集,這裏的指令集是指程序代碼,這裏的系統資源集是指I/O、CPU、內存等。 綜合起來,咱們也能夠理解進程是具備必定獨立功能的程序在關於某個數據集合上的一次運行活動, 進程是系統進行資源分配和調度的一個獨立單位。html

在進程執行時,進程均可以被惟一的表示,由如下一些元素組成:安全

  • 進程描述符:進程的惟一標識符,用來和其它進程區分。在Linux中叫進程ID,在系統調用fork期間生成,只是咱們經過getpid返回的不是其pid字段,而是其線程組號tgid。 
  • 進程狀態:咱們常說的掛起、運行等狀態,其表示的是當前的狀態。 
  • 優先級:進程間的執行調度相關,相對於其它進程而言。 
  • 程序計數器:程序中即將被執行的下一條指令的地址,該地址是內核術中或用戶內存空間中的內存地址。 
  • 內存指針:包括程序代碼和進程相關數據的指針,還有和其它進程共享內存塊的指針。 
  • 上下文數據:進程執行時處理器的寄存器的數據。 
  • I/O狀態信息:包括顯式的I/O請求、分配給進程的I/O設備等 
  • 記帳信息:可能包括處理器時間總和、使用的時鐘數總和、時間限制等

以上的這些元素都會放在一個叫作進程控制塊的數據結構中。進程控制塊是操做系統可以支持多進程和提供多處理的結構。 當操做系統作進程切換時,它會執行兩步操做,一是中斷當前處理器中的進程,二是執行下一個進程。 不論是中斷仍是執行,進程控制塊中的程序計數器、上下文數據和進程狀態都會發生變化。 當進程中斷時,操做系統會把程序計數器和處理器寄存器(對應進程控制塊中的上下文數據)保存到進程控制塊中的相應位置, 進程狀態也會有所變化,可能進入阻塞狀態,也有可能進入就緒態。 當執行下一個進程時,操做系統按規則將下一個進程設置爲運行態,並加載即將要執行進程的程序上下文數據和程序計數器等。數據結構

線程

進程有兩個特性部分:資源全部權和調度執行。 資源全部權是指進程包括了進程運行所須要的內存空間、I/O等資源。 調度執行是指進程執行過程當中間的執行路徑,或者說程序的指令執行流。 這兩個特性部分是能夠分開的,分開後,擁有資料全部權的一般稱爲進程,擁有執行代碼的可分派部分的被稱之爲線程或輕量級進程。多線程

線程有「執行的線索」的意思在裏面,而進程在多線程環境中被定義爲資源全部者,其仍是會存儲進程的進程控制塊。 線程的結構與進程不一樣,每一個線程包括:併發

  • 線程狀態: 線程當前的狀態。 
  • 一個執行棧 
  • 私有的數據區: 用於每一個線程局部變量的靜態存儲空間 
  • 寄存器集: 存儲處理器的一些狀態

每一個進程都有一個進程控制塊和用戶地址空間,每一個線程都有一個獨立的棧和獨立的控制塊,都有本身一個獨立執行上下文。 其結構如圖8.1所示。app

hread-model
圖8.1 進程模型圖

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

線程較之進程,其優點在於一個快,不論是建立新的線程仍是終止一個線程;不論是線程間的切換仍是線程間共享數據或通訊,其速度與進程相比都有較大的優點。php-fpm

併發及並行

併發又稱共行,是指能處理多個同時性活動的能力,併發事件之間不必定要同一時刻發生。 好比,現代計算機系統可在同一段時間內以進程的形式將多個程序加載到存儲器中,並藉由處理器的時分複用, 以在一個處理器上表現出同時運行的感受。工具

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

併發和並行的區別就是一個處理器同時處理多個任務和多個處理器或者是多核的處理器同時處理多個不一樣的任務。 前者是邏輯上的同時發生(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線程的方式。

參考資料

《操做系統精髓與設計原理》

 

http://www.php-internals.com/book/?p=chapt08/08-02-thread-process-and-concurrent

相關文章
相關標籤/搜索