欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

常見進程通信方式

system V共享內(nèi)存

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

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

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

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

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

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

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

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

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'); //將路徑名和項目標識符轉(zhuǎn)換為System V IPC鍵
$shm_id = shm_attach($key,1024,0666);//創(chuàng)建一個大小為1024字節(jié)的共享內(nèi)存存段,權(quán)限為0666,并且將共享內(nèi)存映射關(guān)聯(liá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ù)

父子進程通信

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

配合信號量使用

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

運行結(jié)果:

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

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

我們使用php 提供的另一套擴展來實現(xiàn)

寫進程

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

讀進程

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

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

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

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

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

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

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

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

相關(guān)文章

  • PHP標準庫(PHP SPL)詳解

    PHP標準庫(PHP SPL)詳解

    今天小編就為大家分享一篇關(guān)于PHP標準庫(PHP SPL)詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • php中mail函數(shù)發(fā)送郵件失敗的解決方法

    php中mail函數(shù)發(fā)送郵件失敗的解決方法

    這篇文章主要介紹了php中mail函數(shù)發(fā)送郵件失敗的解決方法,涉及針對Linux運行平臺相關(guān)組件的配置技巧,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • php實現(xiàn)對兩個數(shù)組進行減法操作的方法

    php實現(xiàn)對兩個數(shù)組進行減法操作的方法

    這篇文章主要介紹了php實現(xiàn)對兩個數(shù)組進行減法操作的方法,涉及php操作數(shù)組的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • PHP+Mysql日期時間如何轉(zhuǎn)換(UNIX時間戳和格式化日期)

    PHP+Mysql日期時間如何轉(zhuǎn)換(UNIX時間戳和格式化日期)

    UNIX時間戳和格式化日期是我們常打交道的兩個時間表示形式,Unix時間戳存儲、處理方便,但是不直觀,格式化日期直觀,但是處理起來不如Unix時間戳那么自如,所以有的時候需要互相轉(zhuǎn)換,下面給出互相轉(zhuǎn)換的幾種轉(zhuǎn)換方式
    2012-07-07
  • PHP面向?qū)ο笪宕笤瓌t之依賴倒置原則(DIP)詳解

    PHP面向?qū)ο笪宕笤瓌t之依賴倒置原則(DIP)詳解

    這篇文章主要介紹了PHP面向?qū)ο笪宕笤瓌t之依賴倒置原則(DIP),簡單講述了依賴倒置原則的概念、原理并結(jié)合實例形式分析了php依賴倒置原則相關(guān)定義與使用方法,需要的朋友可以參考下
    2018-04-04
  • php下保存遠程圖片到本地的辦法

    php下保存遠程圖片到本地的辦法

    有些時候我們看到網(wǎng)絡上有一些漂亮的圖片,而又不想手動去保存下來,尤其是大量的這樣的圖片,那這個時候我們需要寫一段程序來幫助我們完成這個工作。
    2010-08-08
  • 高質(zhì)量PHP代碼的50個實用技巧必備(下)

    高質(zhì)量PHP代碼的50個實用技巧必備(下)

    這篇文章主要為大家分享了50個高質(zhì)量PHP代碼的實用技巧,大家必備的php實用代碼,感興趣的小伙伴們可以參考一下
    2016-01-01
  • php隨機獲取金山詞霸每日一句的方法

    php隨機獲取金山詞霸每日一句的方法

    這篇文章主要介紹了php隨機獲取金山詞霸每日一句的方法,實例分析了php通過金山詞霸相關(guān)接口調(diào)用每日一句的實現(xiàn)技巧,需要的朋友可以參考下
    2015-07-07
  • coreseek 搜索英文的問題詳解

    coreseek 搜索英文的問題詳解

    本篇文章是對coreseek搜索英文的問題進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • PHP+mysql防止SQL注入的方法小結(jié)

    PHP+mysql防止SQL注入的方法小結(jié)

    這篇文章主要介紹了PHP+mysql防止SQL注入的方法,結(jié)合實例形式總結(jié)分析了php+mysql程序設計中SQL注入的原理與相應的解決方法,需要的朋友可以參考下
    2019-04-04

最新評論