在線做章網(wǎng)站aso蘋果關鍵詞優(yōu)化
??????
??????????曾經(jīng)初學PHP的時候也很困惑對線程安全與非線程安全模式這塊環(huán)境的選擇,也未能理解其中意。近來無意中看到一個教程對線程安全(餓漢式),非線程安全(懶漢式)的描述,雖然覺得現(xiàn)在已經(jīng)能夠很明了透徹地理解這塊內(nèi)容,但是還是覺得很有必要整理一下以為后來者提供便利。
一、什么是線程安全與非線程安全?
借用網(wǎng)上的一段文來解釋概念。
線程安全就是多線程訪問時,采用了加鎖機制,當一個線程訪問該類的某個數(shù)據(jù)時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程才可使用。不會出現(xiàn)數(shù)據(jù)不一致或者數(shù)據(jù)污染。
線程不安全就是不提供數(shù)據(jù)訪問保護,有可能出現(xiàn)多個線程先后更改數(shù)據(jù)造成所得到的數(shù)據(jù)是臟數(shù)據(jù)。
如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。
線程安全問題都是由全局變量及靜態(tài)變量引起的。
若每個線程中對全局變量、靜態(tài)變量只有讀操作,而無寫操作,一般來說,這個全局變量是線程安全的;若有多個線程同時執(zhí)行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全。
啥個意思呢?小馬認為,其實可以理解為這和業(yè)務邏輯上的db查改并發(fā)控制一樣,只不過對db換成了對內(nèi)存中的全局變量及靜態(tài)變量。解決的方式自然也就是加并發(fā)鎖了,只不過這里的鎖不是我們加,是底層自己維護。《非線性安全并發(fā)例子》
先來看看JAVA對這塊的描述(重點看加粗文字哈):
Java中線程安全和非線程安全:
1、線程安全主要發(fā)生在實例變量或者類變量中,不會發(fā)生在方法的局部變量(可以通過JVM內(nèi)存分布的 棧楨來解釋)。
2、鎖分為三類:
? ? a、類鎖 ? ? - ?靜態(tài)代碼塊鎖發(fā)生。
? ? b、對象鎖 - ?成員方法或者代碼塊鎖發(fā)生。?
? ? c、方法鎖 - 方法上鎖發(fā)生的。
二、PHP線程安全和非線程安全模式的選擇
部分web server在處理應用請求的時候是用多線程而非多進程的方式處理,線程方式因為涉及到共享寄存器和內(nèi)存,所以很容易出錯,這個時候程序就需要花一些額外的經(jīng)歷去處理寄存器中的數(shù)據(jù)一致性,即保證線程安全。所以是否采用線程安全主要看你的web server所采用的PHP請求處理方式,如果是多線程處理,那么請選擇線程安全的,否則選擇非線程安全的,如樓上所說Fast-cgi方式可選擇非線程安全的。
以下就直接選用網(wǎng)上的一段文來描述。
先從字面意思上理解,None-Thread Safe就是非線程安全,在執(zhí)行時不進行線程(thread)安全檢查;Thread Safe就是線程安全,執(zhí)行時會進行線程(thread)安全檢查,以防止有新要求就啟動新線程的 CGI 執(zhí)行方式耗盡系統(tǒng)資源。
再來看PHP的兩種執(zhí)行方式:ISAPI和FastCGI。FastCGI執(zhí)行方式是以單一線程來執(zhí)行操作,所以不需要進行線程的安全檢查,除去線程安全檢查的防護反而可以提高執(zhí)行效率,所以,如果是以 FastCGI(無論搭配 IIS 6 或 IIS 7)執(zhí)行 PHP ,都建議下載、執(zhí)行 non-thread safe 的 PHP (PHP 的二進位檔有兩種包裝方式:msi 、zip ,請下載 zip 套件)。而線程安全檢查正是為ISAPI方式的PHP準備的,因為有許多php模塊都不是線程安全的,所以需要使用Thread Safe的PHP。
說到這里,大家應該知道應該如何選擇哪個版本的PHP了。None-Thread Safe or Thread Safe,您會選擇哪個?
Windows下的PHP現(xiàn)在的版本已經(jīng)是5.3.6,現(xiàn)在的Windows版本可以在PHP官方PHP For Windows(http://windows.php.net/download/)下載,下載的時候同版本有VC9 x86 Non Thread Safe、VC9 x86 Thread Safe、VC6 x86 Non Thread Safe、VC6 x86 Thread Safe等四個版本。那么這些版本有什么區(qū)別呢?
VC9的版本是用legacy VS 2008編譯的,VC6的版本是用legacy VS6編譯的。
如果你是在windows下使用IIS+PHP的話,你需要下載VC9的版本。
如果你是在windows下使用Apache+PHP的話,你需要下載VC6的版本。
Non Thread Safe是指非線程安全,Thread Safe則是指線程安全。
總結:如果是使用ISAPI的方式來運行PHP就必須用Thread Safe(線程安全)的版本;而用FastCGI模式運行PHP的話就沒有必要用線程安全檢查了,用None Thread Safe(NTS,非線程安全)的版本能夠更好的提高效率。
當然理解線程安全和非線程安全這塊知識并不只是為了解決如何選擇PHP運行模式的問題,而是很多需要理解進程模型,并發(fā)編程有著重要的意義,甚至引申到協(xié)程的編碼,協(xié)程間的通信通道的使用等等。