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