PHP進程通訊基礎——信號量+共享內存通訊

PHP進程通訊基礎——信號量+共享內存通訊

因爲進程之間誰先執行並不肯定,這取決於內核的進程調度算法,其中比較複雜。由此有可能多進程在相同的時間內同時訪問共享內存,從而形成不可預料的錯誤。信號量這個名字起的使人莫名其妙,可是看其英文原意,就十分容易理解。
semaphore 英[ˈseməfɔ:(r)] vt. 發出信號,打旗語;
相似於指揮官的做用。
下面咱們看下一個僞代碼信號量的使用。php

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);

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

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) of type (sysvshm)
const SHARE_KEY = 1;
$child_list = [];

//加入信號量
$sem_id = ftok(__FILE__, 'b');
$signal = sem_get($sem_id);

//$signal resource(5) of type (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);
相關文章
相關標籤/搜索