摘要:如果是這樣,就需要引入信號(hào)量進(jìn)行控制。這應(yīng)該是因?yàn)檎诠蚕韮?nèi)存被上一次操作占用中還沒(méi)有釋放導(dǎo)致。
共享內(nèi)存
共享內(nèi)存的使用主要是為了能夠在同一臺(tái)機(jī)器不同的進(jìn)程中共享一些數(shù)據(jù),比如在多個(gè) php-fpm 進(jìn)程中共享當(dāng)前進(jìn)程的使用情況。這種通信也稱為進(jìn)程間通信(Inter-Process Communication),簡(jiǎn)稱 IPC。
PHP 內(nèi)置的 shmop 擴(kuò)展 (Shared Memory Operations) 提供了一系列共享內(nèi)存操作的函數(shù)(可能是用的人不多吧,這一塊兒的文檔還沒(méi)有中文翻譯)。在 Linux 上,這些函數(shù)直接是通過(guò)調(diào)用 shm* 系列的函數(shù)實(shí)現(xiàn),而 Winodows 上也通過(guò)對(duì)系統(tǒng)函數(shù)的封裝實(shí)現(xiàn)了同樣的調(diào)用。
主要函數(shù):
shmop_close?— 關(guān)閉共享內(nèi)存塊
shmop_delete?— 刪除共享內(nèi)存塊
shmop_open?— 創(chuàng)建或打開(kāi)共享內(nèi)存塊
shmop_read?— 從共享內(nèi)存塊中讀取數(shù)據(jù)
shmop_size?— 獲取共享內(nèi)存塊的大小
shmop_write?— 向共享內(nèi)存塊中寫入數(shù)據(jù)
與此相關(guān)的還有一個(gè)很重要的函數(shù):ftok,通過(guò)文件的 inode 信息(*nix 上通過(guò) stat 或 ls -i 命令查看)創(chuàng)建 IPC 的唯一 key(文件/文件夾的 inode 是唯一的)。這個(gè)函數(shù)在 Linux 上也是直接調(diào)用同名的系統(tǒng)函數(shù)實(shí)現(xiàn),Windows 上還是使用一些封裝。
一個(gè)簡(jiǎn)單的計(jì)數(shù)例子:
以上這段代碼沒(méi)執(zhí)行一次計(jì)數(shù)加 1,而且數(shù)據(jù)是在不同進(jìn)程之間共享的。也就是說(shuō)除非手動(dòng)刪除這塊內(nèi)存使用,否則這個(gè)數(shù)據(jù)是不會(huì)重置的。
有個(gè)需要稍微注意的點(diǎn):shmop_open 的第二個(gè)參數(shù)是個(gè) flag,類似 fopen 的第二個(gè)參數(shù),其取值有以前幾個(gè):
"a" 只讀訪問(wèn);
"c" 如果內(nèi)存片段不存在,則創(chuàng)建,如果存在,則可讀寫;
"w" 讀寫;
"n" 創(chuàng)建新的內(nèi)存片段,如果同樣 key 的已存在,則會(huì)創(chuàng)建失敗,這是為了安全使用共享內(nèi)存考慮。
此外,由于使用的共享內(nèi)存片段是固定長(zhǎng)度的,在存儲(chǔ)和讀取的時(shí)候要計(jì)算好數(shù)據(jù)的長(zhǎng)度,不然可能會(huì)寫入失敗或者讀取空值。
信號(hào)控制既然上面使用到了共享內(nèi)存存儲(chǔ)數(shù)據(jù),就需要考慮是否有多個(gè)進(jìn)程同時(shí)寫入數(shù)據(jù)到共享內(nèi)存的情況,是否需要避免沖突。如果是這樣,就需要引入信號(hào)量進(jìn)行控制。
PHP 也提供了類似的內(nèi)置擴(kuò)展 sysvsem(這個(gè)擴(kuò)展在 Windows 環(huán)境下沒(méi)有,文檔中將 ftok 函數(shù)也歸到這個(gè)擴(kuò)展中,但實(shí)際上 ftok 是在標(biāo)準(zhǔn)函數(shù)庫(kù)中提供的,所以在 Windows 下也是可用的)。
在說(shuō)信號(hào)量控制之前,先說(shuō)另外一件有意思的事情:看官方文檔你會(huì)發(fā)現(xiàn)這里同樣也有共享內(nèi)存操作的函數(shù)(shm_*),因?yàn)檫@其實(shí)是同一類別(或者說(shuō)來(lái)自于同一作者)的三個(gè)擴(kuò)展,還有一個(gè)是 sysvmsg(隊(duì)列消息) 。函數(shù)的實(shí)現(xiàn)上稍有差別,但實(shí)際做的事情基本相同。這和上文的 shmop 擴(kuò)展有什么區(qū)別呢?shmop 源碼下的 README 文件有簡(jiǎn)單的說(shuō)明:
PHP already had a shared memory extension (sysvshm) written by Christian Cartus
, unfortunately this extension was designed with PHP only in mind and offers high level features which are extremely bothersome for basic SHM we had in mind. 簡(jiǎn)單說(shuō)來(lái):sysvshm 擴(kuò)展提供的方法并不是原封不動(dòng)的存儲(chǔ)用戶的數(shù)據(jù),而是先使用 PHP 的變量序列化函數(shù)對(duì)參數(shù)進(jìn)行序列化然后再進(jìn)行存儲(chǔ)。這就導(dǎo)致通過(guò)這些方法存儲(chǔ)的數(shù)據(jù)無(wú)法和非 PHP 進(jìn)程共享。不過(guò)這樣也能存儲(chǔ)更豐富的 PHP 數(shù)據(jù)類型,上文的擴(kuò)展中 shmop_write 只能寫入字符串。那么為什么 sysvshm 同樣不支持 Windows 呢?因?yàn)槠洳](méi)有引入封裝了 shm* 系列函數(shù)的 tsrm_win32.h 的頭文件。
引入信號(hào)控制之后的示例:
但是本地想模擬實(shí)現(xiàn)寫入沖突實(shí)際上是非常難的(考慮到計(jì)算機(jī)的執(zhí)行速度)。在本地測(cè)試中,使用 for 循環(huán)操作時(shí)如果不使用 shmop_close 關(guān)閉資源會(huì)出現(xiàn)無(wú)法打開(kāi)共享內(nèi)存的錯(cuò)誤警告。這應(yīng)該是因?yàn)檎诠蚕韮?nèi)存被上一次操作占用中還沒(méi)有釋放導(dǎo)致。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/30350.html
摘要:本人前一遍中提到,當(dāng)進(jìn)程數(shù)過(guò)多時(shí),多進(jìn)程插入數(shù)據(jù)庫(kù)表,超過(guò)了最大連接數(shù),就會(huì)報(bào)錯(cuò),插入就會(huì)有失敗的情況。這樣就可以控制有的連接數(shù)不會(huì)達(dá)到上限,程序不會(huì)出現(xiàn)連接數(shù)據(jù)庫(kù)失敗的情況。多進(jìn)程耗內(nèi)存比較嚴(yán)重,下一步打算用多線程來(lái)試試。 本人前一遍blog中提到,當(dāng)進(jìn)程數(shù)過(guò)多時(shí),多進(jìn)程插入mysql數(shù)據(jù)庫(kù)表,超過(guò)了mysql最大連接數(shù),就會(huì)報(bào)錯(cuò),插入就會(huì)有失敗的情況。想通過(guò)進(jìn)程間通信來(lái)控制一下連接...
摘要:接受不到消息消息隊(duì)列通過(guò)指定而被創(chuàng)建后,任意一方銷毀了該隊(duì)列,都會(huì)導(dǎo)致其他發(fā)送或接收方失敗。用法場(chǎng)景進(jìn)程,中代碼段要用到中代碼段的結(jié)果。完成了進(jìn)程間同步問(wèn)題此外進(jìn)程間通信采用的方式是共享內(nèi)存。 參考文章 深刻理解Linux進(jìn)程間通信(IPC) 進(jìn)程間通信(IPC)介紹 php高級(jí)應(yīng)用之進(jìn)程控制及進(jìn)程間通訊 workman 作者發(fā)布 PHP 相關(guān)進(jìn)程間通信擴(kuò)展 -- System V ...
摘要:一進(jìn)程間通信理解間進(jìn)程通信機(jī)制,先了解下進(jìn)程間有哪些通訊機(jī)制歷史發(fā)展按照歷史來(lái)源主要有兩大塊的管道,,信號(hào)的消息隊(duì)列,共享內(nèi)存,信號(hào)燈。信號(hào)量主要作為進(jìn)程間,以及進(jìn)程內(nèi)部線程之間的通訊手段。主要依賴,兼容擴(kuò)展實(shí)現(xiàn)方式的進(jìn)程間通信之消息隊(duì)列。 PHP間進(jìn)程如何通信,PHP相關(guān)的服務(wù)的IPC是實(shí)現(xiàn)方式,IPC的思想如何用到項(xiàng)目中。 一、linux進(jìn)程間通信 理解php間進(jìn)程通信機(jī)制,先了解...
摘要:目的綜上所述,我的目標(biāo)就是實(shí)現(xiàn)基于模式實(shí)現(xiàn)的多進(jìn)程管理工具。備注下文中,父進(jìn)程統(tǒng)稱為子進(jìn)程統(tǒng)稱為。最后我們通過(guò)下圖來(lái)簡(jiǎn)單的總結(jié)和描述這個(gè)多進(jìn)程實(shí)現(xiàn)的過(guò)程控制上面實(shí)現(xiàn)了多進(jìn)程和多進(jìn)程的常駐內(nèi)存,那如何去管理呢答案多進(jìn)程通信。 _ | | _ __ __ _ _ __...
摘要:為了解決這個(gè)問(wèn)題,我們必須引入互斥機(jī)制。實(shí)現(xiàn)互斥機(jī)制的最簡(jiǎn)單辦法就是使用信號(hào)燈。信號(hào)量是另外一種進(jìn)程間的方式,它同其他機(jī)構(gòu)管道消息隊(duì)列不同。在這個(gè)停車場(chǎng)系統(tǒng)中,車位是公共資源,每輛車好比一個(gè)線程,看門人起的就是信號(hào)量的作用。 在單獨(dú)的一個(gè)PHP進(jìn)程中讀寫、創(chuàng)建、刪除共享內(nèi)存方面上你應(yīng)該沒(méi)有問(wèn)題了。但是實(shí)際運(yùn)行中不可能只是一個(gè)PHP進(jìn)程在運(yùn)行中。如果在多個(gè)進(jìn)程的情況下你還是沿用單個(gè)進(jìn)程的...
閱讀 537·2023-04-25 14:26
閱讀 1292·2021-11-25 09:43
閱讀 3485·2021-09-22 15:25
閱讀 1454·2019-08-30 15:54
閱讀 528·2019-08-30 12:57
閱讀 773·2019-08-29 17:24
閱讀 3170·2019-08-28 18:13
閱讀 2691·2019-08-28 17:52