這篇文章主要介紹了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);
#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);