最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

php進(jìn)程通信之共享內(nèi)存詳細(xì)講解

 更新時(shí)間:2022年09月10日 10:07:46   作者:大雷編程  
這篇文章主要介紹了php進(jìn)程通信之共享內(nèi)存,共享內(nèi)存是一種最為高效的進(jìn)程間通信(IPC)方式,進(jìn)程可以直接讀寫內(nèi)存,而不需要任何數(shù)據(jù)的拷貝

常見進(jìn)程通信方式

system V共享內(nèi)存

現(xiàn)代操作系統(tǒng),對(duì)于內(nèi)存管理,采用的是虛擬內(nèi)存技術(shù),也就是每個(gè)進(jìn)程都有自己獨(dú)立的虛擬內(nèi)存空間,不同進(jìn)程的虛擬內(nèi)存映射到不同的物理內(nèi)存中。所以,即使進(jìn)程 A 和 進(jìn)程 B 的虛擬地址是一樣的,其實(shí)訪問(wèn)的是不同的物理內(nèi)存地址,對(duì)于數(shù)據(jù)的增刪查改互不影響。

共享內(nèi)存的機(jī)制,就是拿出一塊虛擬地址空間來(lái),映射到相同的物理內(nèi)存中。這樣這個(gè)進(jìn)程寫入的東西,另外一個(gè)進(jìn)程馬上就能看到了,不需要經(jīng)過(guò)數(shù)次的拷貝(比如從輸入緩沖區(qū)中拷貝到文件中、再拷貝到輸出緩沖區(qū)中等),大大提高了進(jìn)程間通信的速度。

在所有進(jìn)程間通信的方式中共享內(nèi)存的效率是最高的。

共享內(nèi)存操作默認(rèn)不阻塞,如果多個(gè)進(jìn)程同時(shí)讀寫共享內(nèi)存,可能出現(xiàn)數(shù)據(jù)混亂,共享內(nèi)存需要借助其他機(jī)制來(lái)保證進(jìn)程間的數(shù)據(jù)同步,比如:上期講信號(hào)量,共享內(nèi)存內(nèi)部沒有提供這種同步機(jī)制。

通過(guò)上圖可知,共享內(nèi)存是通過(guò)將不同進(jìn)程的虛擬內(nèi)存地址映射到相同的物理內(nèi)存地址來(lái)實(shí)現(xiàn)的

頁(yè)表是一種特殊的數(shù)據(jù)結(jié)構(gòu),放在系統(tǒng)空間的頁(yè)表區(qū),存放邏輯頁(yè)(虛擬內(nèi)存)與物理頁(yè)幀(物理內(nèi)存)的對(duì)應(yīng)關(guān)系。 每一個(gè)進(jìn)程都擁有一個(gè)自己的頁(yè)表。

php使用共享內(nèi)存

php 提供了兩套操作共享內(nèi)存的擴(kuò)展,兩套擴(kuò)展都實(shí)現(xiàn)了相同的功能,用哪個(gè)看你喜歡

https://www.php.net/manual/en/ref.shmop.php

https://www.php.net/manual/en/ref.sem.php

共享內(nèi)存基本函數(shù)使用

<?php
$key = ftok('demo1.php','x'); //將路徑名和項(xiàng)目標(biāo)識(shí)符轉(zhuǎn)換為System V IPC鍵
$shm_id = shm_attach($key,1024,0666);//創(chuàng)建一個(gè)大小為1024字節(jié)的共享內(nèi)存存段,權(quán)限為0666,并且將共享內(nèi)存映射關(guān)聯(lián)到當(dāng)前進(jìn)程的地址空間
shm_put_var($shm_id,1,'hello world');//往共享內(nèi)存里寫入數(shù)據(jù)
echo "共享內(nèi)存:".shm_get_var($shm_id,1).PHP_EOL;//讀取共享內(nèi)存里數(shù)據(jù)

父子進(jìn)程通信

<?php
$key = ftok('demo4.php','x');
// $shm_id 它對(duì)應(yīng)當(dāng)前進(jìn)程的地址空間,實(shí)際是映射連接了系統(tǒng)分配的共享區(qū)域(共享內(nèi)存)
$shm_id = shm_attach($key,1024,0666);//創(chuàng)建一個(gè)大小為1024字節(jié)的共享內(nèi)存存段,權(quán)限為0666,并且將共享內(nèi)存映射關(guān)聯(lián)到當(dāng)前進(jìn)程的地址空間
$pid = pcntl_fork();// fork 子進(jìn)程
if($pid == 0){//子進(jìn)程運(yùn)行邏輯
   echo shm_get_var($shm_id,1).PHP_EOL;//讀取共享內(nèi)存數(shù)據(jù)
	exit(0);
}
//父進(jìn)程運(yùn)行邏輯
shm_put_var($shm_id,1,'hello world');//寫入數(shù)據(jù)到共享內(nèi)存,第三個(gè)參數(shù)可以傳入任意數(shù)據(jù)類型
pcntl_wait($status);//等待子進(jìn)程退出釋放資源,防止僵尸進(jìn)程
// 刪除共享內(nèi)存是有順序的,先remove后detach,順序反過(guò)來(lái)php可能會(huì)報(bào)錯(cuò)
shm_remove($shm_id);//從系統(tǒng)中移除共享內(nèi)存
shm_detach($shm_id);//斷開進(jìn)程與共享內(nèi)存的映射關(guān)系

配合信號(hào)量使用

<?php
// sem key
$sem_key = ftok( __FILE__, 'b' );//信號(hào)量key
$sem_id = sem_get( $sem_key );//獲取信號(hào)量
// shm key
$shm_key = ftok( __FILE__, 'm' );//共享內(nèi)存key
$shm_id = shm_attach( $shm_key, 1024, 0666 );//創(chuàng)建一個(gè)大小為1024字節(jié)的共享內(nèi)存存段,權(quán)限為0666,并且將共享內(nèi)存映射關(guān)聯(lián)到當(dāng)前進(jìn)程的地址空間
$child_pid = [];
// fork 2 子進(jìn)程
for( $i = 1; $i <= 2; $i++ ){
  $pid = pcntl_fork();  
  if( $pid < 0 ){
    exit();
  } else if( 0 == $pid ) {//子進(jìn)程運(yùn)行邏輯
	// 獲取鎖
	sem_acquire( $sem_id );
	// 檢測(cè)共享內(nèi)存是否有值
	if( shm_has_var( $shm_id, 1) ){
	  //shm_get_var第二參數(shù)必須是int型
	  $counter = shm_get_var( $shm_id, 1);
	  $counter += 1;
	  shm_put_var( $shm_id, 1, $counter );//寫入共享內(nèi)存
	} else {
	  $counter = 1;
	  shm_put_var( $shm_id, 1, $counter );//寫入共享內(nèi)存
	}
	// 釋放鎖,一定要記得釋放,不然就一直會(huì)被阻鎖死
	sem_release( $sem_id );
	exit;
  } else if( $pid > 0 ) {//父進(jìn)程運(yùn)行邏輯
    $child_pid[] = $pid;
  }
}
while( !empty( $child_pid ) ){
  foreach( $child_pid as $pid_key => $pid_item ){
        $wait_result=pcntl_waitpid( $pid_item, $status, WNOHANG );
	//必須判斷子進(jìn)程回收的狀態(tài),如果不加判斷,第一次兩個(gè)子進(jìn)程返回都是0,直接unset后會(huì)無(wú)法進(jìn)入while,導(dǎo)致僵尸進(jìn)程
        if($wait_result == -1 || $wait_result > 0)
	unset( $child_pid[ $pid_key ] );
  }
}
// 休眠2秒鐘,2個(gè)子進(jìn)程都執(zhí)行完畢了
sleep( 2 );
echo '最終結(jié)果'.shm_get_var( $shm_id, 1 ).PHP_EOL;
// 刪除共享內(nèi)存是有順序的,先remove后detach,順序反過(guò)來(lái)php可能會(huì)報(bào)錯(cuò)
shm_remove( $shm_id );
shm_detach( $shm_id );

運(yùn)行結(jié)果:

如果不使用信號(hào)量,運(yùn)行結(jié)果有一定概率會(huì)產(chǎn)生1而不是2。但是只要加入信號(hào)量sem,就一定保證100%是2,絕對(duì)不會(huì)出現(xiàn)其他數(shù)值。

非血緣關(guān)系進(jìn)程共享內(nèi)存通信

我們使用php 提供的另一套擴(kuò)展來(lái)實(shí)現(xiàn)

寫進(jìn)程

<?php
$key = ftok('a.php','x');
$shm_id = shmop_open($key,'c',0664,1204);//創(chuàng)建一個(gè)大小為1024字節(jié)的共享內(nèi)存存段,權(quán)限為0666,并且將共享內(nèi)存映射關(guān)聯(lián)到當(dāng)前進(jìn)程的地址空間, 第二個(gè)參數(shù)為 'c' 表示共享內(nèi)存段不存在就創(chuàng)建,存在就直接連接打開
shmop_write($shm_id,'學(xué)無(wú)止境',0); // 寫入數(shù)據(jù) ,第三個(gè)參數(shù)代表寫入數(shù)據(jù)的偏移量

讀進(jìn)程

<?php
$key = ftok('a.php','x');
$shm_id = shmop_open($key,'c',0664,1204);//創(chuàng)建一個(gè)大小為1024字節(jié)的共享內(nèi)存存段,權(quán)限為0666,并且將共享內(nèi)存映射關(guān)聯(lián)到當(dāng)前進(jìn)程的地址空間, 第二個(gè)參數(shù)為 'c' 表示共享內(nèi)存段不存在就創(chuàng)建,存在就直接連接打開
echo shmop_read($shm_id,0,20).PHP_EOL; //讀取共享段內(nèi)容,第二個(gè)參數(shù)讀取內(nèi)存偏移量,第三個(gè)參數(shù)是要讀取的字節(jié)數(shù)
shmop_delete($shm_id);//從系統(tǒng)中刪除共享內(nèi)存段

共享內(nèi)存的特性

生命周期跟隨操作系統(tǒng)

可以通過(guò)ipcs命令查看共享內(nèi)存

共享內(nèi)存采用的是覆蓋寫的方式,讀的時(shí)候,是訪問(wèn)地址。

覆蓋寫可以理解為,再次往共享內(nèi)存中寫的時(shí)候,會(huì)先將共享內(nèi)存中的內(nèi)容清空,再寫入。

讀的時(shí)候, 是訪問(wèn)地址,區(qū)別于管道是將數(shù)據(jù)讀走了,而在共享內(nèi)存中讀的時(shí)候并沒有將數(shù)據(jù)讀走,僅僅是訪問(wèn)地址。

到此這篇關(guān)于php進(jìn)程通信之共享內(nèi)存詳細(xì)講解的文章就介紹到這了,更多相關(guān)php共享內(nèi)存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PHP中使用反射獲取類的所有方法

    PHP中使用反射獲取類的所有方法

    在 PHP 開發(fā)中,了解類的結(jié)構(gòu)和行為對(duì)于調(diào)試、測(cè)試以及構(gòu)建可擴(kuò)展的應(yīng)用至關(guān)重要,有時(shí),你可能需要?jiǎng)討B(tài)地獲取一個(gè)類的所有方法,PHP 的反射 API 提供了一種強(qiáng)大且靈活的方式來(lái)實(shí)現(xiàn)這一目標(biāo),接下來(lái)給大家詳細(xì)介紹PHP中使用反射獲取類的所有方法
    2024-11-11
  • 關(guān)于JSON以及JSON在PHP中的應(yīng)用技巧

    關(guān)于JSON以及JSON在PHP中的應(yīng)用技巧

    這篇文章主要介紹了關(guān)于JSON以及JSON在PHP中的應(yīng)用技巧。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-11-11
  • 解析:通過(guò)php socket并借助telnet實(shí)現(xiàn)簡(jiǎn)單的聊天程序

    解析:通過(guò)php socket并借助telnet實(shí)現(xiàn)簡(jiǎn)單的聊天程序

    本篇文章是對(duì)通過(guò)php socket并借助telnet實(shí)現(xiàn)簡(jiǎn)單聊天程序的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • PHP面向?qū)ο蟪绦蛟O(shè)計(jì)繼承用法簡(jiǎn)單示例

    PHP面向?qū)ο蟪绦蛟O(shè)計(jì)繼承用法簡(jiǎn)單示例

    這篇文章主要介紹了PHP面向?qū)ο蟪绦蛟O(shè)計(jì)繼承用法,結(jié)合具體實(shí)例形式分析了php面向?qū)ο蟪绦蛟O(shè)計(jì)中繼承的相關(guān)概念、原理、使用技巧與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-12-12
  • 淺談php和js中json的編碼和解碼

    淺談php和js中json的編碼和解碼

    下面小編就為大家?guī)?lái)一篇淺談php和js中json的編碼和解碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-10-10
  • php匹配字符中鏈接地址的方法

    php匹配字符中鏈接地址的方法

    這篇文章主要介紹了php匹配字符中鏈接地址的方法,涉及正則匹配與提取超鏈接的方法,是非常實(shí)用的正則技巧,需要的朋友可以參考下
    2014-12-12
  • PHP 函數(shù)call_user_func和call_user_func_array用法詳解

    PHP 函數(shù)call_user_func和call_user_func_array用法詳解

    下面來(lái)和大家分享一下這個(gè)call_user_func_array和call_user_func函數(shù)的用法,另外附贈(zèng)func_get_args()函數(shù)和func_num_args()函數(shù),嘿嘿!!
    2014-03-03
  • 處理php自動(dòng)反斜杠的函數(shù)代碼

    處理php自動(dòng)反斜杠的函數(shù)代碼

    處理php自動(dòng)反斜杠的實(shí)現(xiàn)函數(shù)
    2010-01-01
  • php解決DOM亂碼的方法示例代碼

    php解決DOM亂碼的方法示例代碼

    最近在工作的時(shí)候遇到一個(gè)問(wèn)題,在使用DOM的時(shí)候,發(fā)現(xiàn)了亂碼的問(wèn)題,后來(lái)通過(guò)查找網(wǎng)上的資料終于解決了,現(xiàn)在將解決的方法分享給大家,感興趣的朋友們可以參考借鑒,有需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • php反射學(xué)習(xí)之依賴注入示例

    php反射學(xué)習(xí)之依賴注入示例

    這篇文章主要介紹了php反射學(xué)習(xí)之依賴注入,結(jié)合具體實(shí)例形式分析了php基于反射的依賴注入原理與實(shí)現(xiàn)方法,需要的朋友可以參考下
    2019-06-06

最新評(píng)論

齐河县| 嘉荫县| 平遥县| 荥经县| 武穴市| 斗六市| 吉安县| 镇巴县| 宜良县| 华安县| 安龙县| 铁岭市| 灵丘县| 江孜县| 新乐市| 改则县| 定襄县| 古田县| 琼结县| 华池县| 杭州市| 上杭县| 神木县| 黄龙县| 阜城县| 崇文区| 康马县| 军事| 林周县| 自贡市| 涿州市| 柞水县| 石家庄市| 永嘉县| 扎囊县| 山东省| 盘锦市| 鹤岗市| 祁连县| 绵竹市| 揭东县|