萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP進程通信基礎之信號量與共享內存通信

PHP進程通信基礎之信號量與共享內存通信

本文介紹了PHP進程通信基礎之信號量與共享內存通信,非常實用,大家可以參考一下。

由於進程之間誰先執行並不確定,這取決於內核的進程調度算法,其中比較復雜。由此有可能多進程在相同的時間內同時訪問共享內存,從而造成不可預料的錯誤。信號量這個名字起的令人莫名其妙,但是看其英文原意,就十分容易理解。

semaphore 英[ˈseməfɔ:(r)] vt. 發出信號,打旗語;

類似於指揮官的作用。

下面我們看下一個偽代碼信號量的使用。

1、創建信號量唯一標識符

$ftok = ftok(__FILE__, 'a');

2、創建信號量資源ID

$sem_resouce_id = sem_get($ftok);

3、接受信號量

sem_acqure($sem_resource_id);

4、釋放信號量

sem_release($sem_resource_id);

5、銷毀信號量

sem_remove($sem_resource_id);

舉個不文雅的例子,使我們容易理解這個信號量在生活中的用法。理解之後可以套用到我們編程領域。
一家公司只有一個衛生間。那麼當有人上廁所的時候,都要獲取一把鎖(信號量),表示衛生間正在使用。代碼如下:

sem_acqure($sem_resource_id);

那麼員工上完廁所之後,就需要將鎖打開,釋放鎖(信號量),表示現在可以允許別人使用。代碼如下:

sem_release($sem_resource_id);

通過一個簡單的鎖,我們就能夠知道當前的廁所(共享內存)是否可以使用。這個例子不雅觀,但說明了問題。這篇博客也是有味道的博客,真是不容易。。。。以下是示例代碼:

 

 代碼如下復制代碼

<?php

//創建共享內存區域

$shm_key = ftok(__FILE__,'a');

$shm_id = shm_attach($shm_key, 1024, 0755);

 

//var_dump($shm_id);die(); resource(4) oftype(sysvshm)

const SHARE_KEY = 1;

$child_list = [];

 

//加入信號量

$sem_id = ftok(__FILE__,'b');

$signal = sem_get($sem_id);

 

//$signal resource(5) oftype(sysvsem)

 

 

for($i = 0; $i < 3; $i++) {

  $pid = pcntl_fork();

  if($pid == -1) {

    exit("Fork fail!".PHP_EOL);

  } elseif ($pid == 0) {

    //獲取信號量

    sem_acquire($signal);

    if(shm_has_var($shm_id,SHARE_KEY)) {

      $count = shm_get_var($shm_id, SHARE_KEY);

      $count++;

      //模擬業務處理

      $sec = rand(1, 3);

      sleep($sec);

      shm_put_var($shm_id, SHARE_KEY, $count);

    }else{

      $count = 0;

      $sec = rand(1, 3);

      sleep($sec);

      shm_put_var($shm_id, SHARE_KEY, $count);

    }

 

    echo"child process: ".getmypid()." is writing! now count is: $count ".PHP_EOL;

 

    //釋放信號量

    sem_release($signal);

    exit("child process".getmypid()."end".PHP_EOL);

  }else{

    $child_list[] = $pid;

  }

}

 

while(count($child_list) > 0) {

  foreach ($child_list as $key => $pid) {

    $status = pcntl_waitpid($pid, $status);

    if($status > 0 || $status == -1) {

      unset($child_list[$key]);

    }

  }

  sleep(1);

}

 

$count = shm_get_var($shm_id, SHARE_KEY);

echo" $count  ".PHP_EOL;

 

//銷毀信號量

sem_remove($signal);

 

shm_remove($shm_id);

shm_detach($shm_id);

 

copyright © 萬盛學電腦網 all rights reserved