国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

(PHP7內(nèi)核剖析-10) 線程安全

Achilles / 2395人閱讀

摘要:中專門為解決線程安全的問(wèn)題抽象出了一個(gè)線程安全資源管理器,實(shí)現(xiàn)原理比較簡(jiǎn)單既然共用資源這么困難那么就干脆不共用,各線程不再共享同一份全局變量,而是各復(fù)制一份,使用數(shù)據(jù)時(shí)各線程各取自己的副本,互不干擾。

1.線程安全資源管理器

PHP的SAPI多數(shù)是單線程環(huán)境,比如cli、fpm、cgi,每個(gè)進(jìn)程只啟動(dòng)一個(gè)主線程,這種模式下是不存在線程安全問(wèn)題的,但是也有多線程的環(huán)境,比如Apache,這種情況下就需要考慮線程安全的問(wèn)題了,因?yàn)镻HP中有很多全局變量,比如最常見的:EG、CG,如果多個(gè)線程共享同一個(gè)變量將會(huì)沖突,所以PHP為多線程的應(yīng)用模型提供了一個(gè)安全機(jī)制:Zend線程安全(Zend Thread Safe, ZTS)。
PHP中專門為解決線程安全的問(wèn)題抽象出了一個(gè)線程安全資源管理器(Thread Safe Resource Mananger, TSRM),實(shí)現(xiàn)原理比較簡(jiǎn)單:既然共用資源這么困難那么就干脆不共用,各線程不再共享同一份全局變量,而是各復(fù)制一份,使用數(shù)據(jù)時(shí)各線程各取自己的副本,互不干擾。
typedef struct {
    size_t size; //資源的大小
    ts_allocate_ctor ctor; //初始化函數(shù)
    ts_allocate_dtor dtor;
    int done;
} tsrm_resource_type;

struct _tsrm_tls_entry {
    void **storage; //資源數(shù)組
    int count; //擁有的資源數(shù):storage數(shù)組大小
    THREAD_T thread_id; //所屬線程id
    tsrm_tls_entry *next;
};
如果一個(gè)資源會(huì)被多線程使用,那么首先需要預(yù)先向TSRM注冊(cè)資源,然后TSRM為這個(gè)資源分配一個(gè)唯一的編號(hào),并把這種資源的大小、初始化函數(shù)等保存到一個(gè)tsrm_resource_type結(jié)構(gòu)中,各線程只能通過(guò)TSRM分配的那個(gè)編號(hào)訪問(wèn)這個(gè)資源;然后當(dāng)線程拿著這個(gè)編號(hào)獲取資源時(shí)TSRM如果發(fā)現(xiàn)是第一次請(qǐng)求,則會(huì)根據(jù)注冊(cè)時(shí)的資源大小分配一塊內(nèi)存,然后調(diào)用初始化函數(shù)進(jìn)行初始化,并把這塊資源保存下來(lái)供這個(gè)線程后續(xù)使用。
每個(gè)線程擁有一個(gè)tsrm_tls_entry結(jié)構(gòu),當(dāng)前線程的所有資源保存在storage數(shù)組中,下標(biāo)就是各資源的id。另外所有線程的tsrm_tls_entry結(jié)構(gòu)通過(guò)一個(gè)數(shù)組保存:tsrm_tls_table,這是個(gè)全局變量,每個(gè)線程的tsrm_tls_entry結(jié)構(gòu)在這個(gè)數(shù)組中的位置是根據(jù)線程id與預(yù)設(shè)置的線程數(shù)(tsrm_tls_table_size)取模得到的,也就是說(shuō)有可能多個(gè)線程保存在tsrm_tls_table同一位置,所以tsrm_tls_entry是個(gè)鏈表,查找資源時(shí)首先根據(jù):線程id % tsrm_tls_table_size得到一個(gè)tsrm_tls_entry,然后開始遍歷鏈表比較thread_id確定是否是當(dāng)前線程的。

線程本地存儲(chǔ)(Thread Local Storage, TLS),在創(chuàng)建完當(dāng)前線程的tsrm_tls_entry后會(huì)把這個(gè)值保存到當(dāng)前線程的TLS中,這樣在ts_resource()獲取資源時(shí)中就可以通過(guò)tsrm_tls_get()直接取到了,節(jié)省加鎖檢索的時(shí)間。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/28582.html

相關(guān)文章

  • (PHP7內(nèi)核剖析-9) 內(nèi)存管理

    摘要:但在多線程模式下會(huì)有多個(gè),也就是說(shuō)每個(gè)線程都有一個(gè)獨(dú)立的內(nèi)存池內(nèi)存分配分配超過(guò)內(nèi)存的申請(qǐng),與通用的內(nèi)存申請(qǐng)沒有太大差別,只是將申請(qǐng)的內(nèi)存塊通過(guò)單鏈表進(jìn)行了管理。的分配實(shí)際就是分配多個(gè),的分配也是內(nèi)存分配的基礎(chǔ),它是向系統(tǒng)申請(qǐng)內(nèi)存的唯一粒度。 1.Zend內(nèi)存池 內(nèi)存池是內(nèi)核中最底層的內(nèi)存操作,定義了三種粒度的內(nèi)存塊:chunk、page、slot,每個(gè)chunk的大小為2M,page大...

    ygyooo 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-3) 變量

    摘要:插入一個(gè)元素時(shí)先將元素按先后順序插入數(shù)組,位置是,再根據(jù)的哈希值映射到散列表中的某個(gè)位置,將存入這個(gè)位置查找時(shí)先在散列表中映射到,得到在數(shù)組的位置,再?gòu)臄?shù)組中取出元素。目前只有兩種類型會(huì)使用這種機(jī)制。 1.變量結(jié)構(gòu) typedef struct _zval_struct zval; typedef union _zend_value { zend_long ...

    RiverLi 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-4) 局部變量,全局變量,常量

    摘要:局部變量中局部變量分配在結(jié)構(gòu)上,每次執(zhí)行都會(huì)生成一個(gè)新的,局部變量在執(zhí)行之初分配,然后在執(zhí)行結(jié)束時(shí)釋放,這是局部變量的生命周期。 1.局部變量 PHP中局部變量分配在zend_execute_data結(jié)構(gòu)上,每次執(zhí)行zend_op_array都會(huì)生成一個(gè)新的zend_execute_data,局部變量在執(zhí)行之初分配,然后在執(zhí)行結(jié)束時(shí)釋放,這是局部變量的生命周期。 讀寫操作:局部變量通過(guò)...

    yagami 評(píng)論0 收藏0
  • (PHP7內(nèi)核剖析-5) PHP代碼的編譯

    摘要:代碼的編譯的解析過(guò)程任務(wù)就是將代碼轉(zhuǎn)化為數(shù)組,代碼里的所有信息都保存在數(shù)組中,然后將數(shù)組交給引擎執(zhí)行,就是內(nèi)核具體執(zhí)行的命令,比如賦值加減操作函數(shù)調(diào)用等,每一條都對(duì)應(yīng)一個(gè)處理,這些是提前定義好的函數(shù)。 1.PHP代碼的編譯 PHP的解析過(guò)程任務(wù)就是將PHP代碼轉(zhuǎn)化為opcode數(shù)組,代碼里的所有信息都保存在opcode數(shù)組中,然后將opcode數(shù)組交給zend引擎執(zhí)行,opcode就是...

    DevTTL 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<