信號量與共享內(nèi)存氏涩。共享內(nèi)存是最快是進程間通信方式酬诀,因為n個進程之間并不需要數(shù)據(jù)復(fù)制曹质,而是直接操控同一份數(shù)據(jù)婴噩。實際上信號量和共享內(nèi)存是分不開的,要用也是搭配著用羽德。*NIX的一些書籍中甚至不建議新手輕易使用這種進程間通信的方式几莽,因為這是一種極易產(chǎn)生死鎖的解決方案。共享內(nèi)存顧名思義宅静,就是一坨內(nèi)存中的區(qū)域章蚣,可以讓多個進程進行讀寫。這里最大的問題就在于數(shù)據(jù)同步的問題姨夹,比如一個在更改數(shù)據(jù)的時候纤垂,另一個進程不可以讀,不然就會產(chǎn)生問題匀伏。所以為了解決這個問題才引入了信號量洒忧,信號量是一個計數(shù)器,是配合共享內(nèi)存使用的.
<?php
//ftok將一個路徑名pathname和一個項目名(必須為一個字符), 轉(zhuǎn)化成一個整形的用來使用系統(tǒng)V IPC的key
$sem_key = ftok( __FILE__, 'b' );
// 獲取信號id
$sem_id = sem_get( $sem_key );
//ftok將一個路徑名pathname和一個項目名(必須為一個字符), 轉(zhuǎn)化成一個整形的用來使用系統(tǒng)V IPC的key
$shm_key = ftok( __FILE__, 'm' );
// 創(chuàng)建一個共享內(nèi)存
$shm_id = shm_attach( $shm_key, 1024, 0666 );
const SHM_VAR = 1;
$child_pid = [];
for( $i = 1; $i <= 2; $i++ ){
$pid = pcntl_fork();
if( $pid < 0 ){
exit();
} else if( 0 == $pid ) {
// 獲取信號量(獲取鎖)
sem_acquire( $sem_id );
// 判斷此信號量中是否有值
if( shm_has_var( $shm_id, SHM_VAR ) ){
$counter = shm_get_var( $shm_id, SHM_VAR );
$counter += 1;
shm_put_var( $shm_id, SHM_VAR, $counter );
} else {
$counter = 1;
shm_put_var( $shm_id, SHM_VAR, $counter );
}
// 釋放信號量(釋放鎖)
sem_release( $sem_id );
exit;
} else if( $pid > 0 ) {
$child_pid[] = $pid;
}
}
while( !empty( $child_pid ) ){
foreach( $child_pid as $pid_key => $pid_item ){
pcntl_waitpid( $pid_item, $status, WNOHANG );
unset( $child_pid[ $pid_key ] );
}
}
sleep( 2 );
echo '最終結(jié)果'.shm_get_var( $shm_id, SHM_VAR ).PHP_EOL;
// 刪除共享內(nèi)存數(shù)據(jù)够颠,刪除共享內(nèi)存是有順序的熙侍,先remove后detach
shm_remove( $shm_id );
shm_detach( $shm_id );