多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 深入研究PHP及Zend Engine的線程安全模型

深入研究PHP及Zend Engine的線程安全模型

來源:程序員人生   發布時間:2013-10-28 02:08:43 閱讀次數:2676次

在閱讀PHP源碼和學習PHP擴展開發的過程中,我接觸到大量含有“TSRM”字眼的宏。通過查閱資料,知道這些宏與Zend的線程安全機制有關,而絕大多數資料中都建議按照既定規則使用這些宏就可以,而沒有說明這些宏的具體作用。不知道怎么回事總是令人不舒服的,因此我通過閱讀源碼和查閱有限的資料簡要了解一下相關機制,本文是我對研究內容的總結。
本文首先解釋了線程安全的概念及PHP中線程安全的背景,然后詳細研究了PHP的線程安全機制ZTS(Zend Thread Safety)及具體的實現TSRM,研究內容包括相關數據結構、實現細節及運行機制,最后研究了Zend對于單線程和多線程環境的選擇性編譯問題。

線程安全

線程安全問題,一言以蔽之就是多線程環境下如何安全存取公共資源。我們知道,每個線程只擁有一個私有棧,共享所屬進程的堆。在C中,當一個變量被聲明在任何函數之外時,就成為一個全局變量,這時這個變量會被分配到進程的共享存儲空間,不同線程都引用同一個地址空間,因此一個線程如果修改了這個變量,就會影響到全部線程。這看似為線程共享數據提供了便利,但是PHP往往是每個線程處理一個請求,因此希望每個線程擁有一個全局變量的副本,而不希望請求間相互干擾。

早期的PHP往往用于單線程環境,每個進程只啟動一個線程,因此不存在線程安全問題。后來出現了多線程環境下使用PHP的場景,因此Zend引入了Zend線程安全機制(Zend Thread Safety,簡稱ZTS)用于保證線程的安全。

ZTS的基本原理及實現

基本思想

說起來ZTS的基本思想是很直觀的,不是就是需要每個全局變量在每個線程都擁有一個副本嗎?那我就提供這樣的機制:

在多線程環境下,申請全局變量不再是簡單聲明一個變量,而是整個進程在堆上分配一塊內存空間用作“線程全局變量池”,在進程啟動時初始化這個內存池,每當有線程需要申請全局變量時,通過相應方法調用TSRM(Thread Safe Resource Manager,ZTS的具體實現)并傳遞必要的參數(如變量大小等等),TSRM負責在內存池中分配相應內存區塊并將這塊內存的引用標識返回,這樣下次這個線程需要讀寫此變量時,就可以通過將唯一的引用標識傳遞給TSRM,TSRM將負責真正的讀寫操作。這樣就實現了線程安全的全局變量。下圖給出了ZTS原理的示意圖:

image

Thread1和Thread2同屬一個進程,其中各自需要一個全局變量Global Var,TSRM為兩者在線程全局內存池中(黃色部分)各自分配了一個區域,并且通過唯一的ID進行標識,這樣兩個線程就可以通過TSRM存取自己的變量而互不干擾。

下面通過具體的代碼片段看一下Zend具體是如何實現這個機制的。這里我用的是PHP5.3.8的源碼。

TSRM的實現代碼在PHP源碼的“TSRM”目錄下。

數據結構

TSRM中比較重要的數據結構有兩個:tsrm_tls_entry和tsrm_resource_type。下面先看tsrm_tls_entry。

tsrm_tls_entry定義在TSRM/TSRM.c中:

typedef struct _tsrm_tls_entry tsrm_tls_entry;struct _tsrm_tls_entry {	void **storage;	int count;	THREAD_T thread_id;	tsrm_tls_entry *next;}

每個tsrm_tls_entry結構負責表示一個線程的所有全局變量資源,其中thread_id存儲線程ID,count記錄全局變量數,next指向下一個節點。storage可以看做指針數組,其中每個元素是一個指向本節點代表線程的一個全局變量。最終各個線程的tsrm_tls_entry被組成一個鏈表結構,并將鏈表頭指針賦值給一個全局靜態變量tsrm_tls_table。注意,因為tsrm_tls_table是一個貨真價實的全局變量,所以所有線程會共享這個變量,這就實現了線程間的內存管理一致性。tsrm_tls_entry和tsrm_tls_table結構的示意圖如下:

image

tsrm_resource_type的內部結構相對簡單一些:

typedef struct {	size_t size;	ts_allocate_ctor ctor;	ts_allocate_dtor dtor;	int done;} tsrm_resource_type;

上文說過tsrm_tls_entry是以線程為單位的(每個線程一個節點),而tsrm_resource_type以資源(或者說全局變量)為單位,每次一個新的資源被分配時,就會創建一個tsrm_resource_type。所有tsrm_resource_type以數組(線性表)的方式組成tsrm_resource_table,其下標就是這個資源的ID。每個tsrm_resource_type存儲了此資源的大小和構造、析構方法指針。某種程度上,tsrm_resource_table可以看做是一個哈希表,key是資源ID,value是tsrm_resource_type結構。

精彩內容,請點擊下一頁!

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品v欧美精品v日本精 | 欧美人与牲动交xxxxbbbb | 国产一区二区三区在线免费观看 | 精品一二三区 | 手机看片福利在线 | 欧美巨大xxxx做受孕妇视频 | 欧美日韩一区二区三区色综合 | 极品色影视| 最近更新中文字幕3 | 俺去啦最新网址 | 欧美另类精品一区二区三区 | 久久久久久久综合 | 国产成人免费手机在线观看视频 | 一级一级一级毛片免费毛片 | 精品国产亚洲一区二区三区 | 亚洲人在线播放 | 18videosex性欧美黑色 | 日本成人一区二区三区 | 日韩在线影视 | 亚洲高清视频免费 | 日本在线看免费 | 久久受www免费人成看片 | 欧洲精品一区二区三区在线观看 | 国产亚洲欧美精品久久久 | 日韩激情中文字幕一区二区 | 一区二区三区不卡在线 | 亚洲毛片免费在线观看 | 日韩久久久精品中文字幕 | 日本大胆欧美艺术337p | 9久热久爱免费精品视频在线观看 | 日韩精品一区二三区中文 | 欧美性视频一区二区三区 | 91福利影院| 日韩欧美一区二区不卡看片 | 边摸边吃奶边做娇喘视频 | www.日本一区 | www视频免费观看 | 色老成人精品视频在线观看 | 欧美色图一区二区 | 国产91精品久久久久久久 | tube日本黑人杂交 |