下面都是自己程序驗(yàn)證的,如果有說的不對(duì)的, 請(qǐng)指出
驗(yàn)證原因:之前自己看workerman源碼,寫相關(guān)的信號(hào),進(jìn)程程序,模仿網(wǎng)上開始寫,碰到declare(ticks=1),查資料說是讓進(jìn)程自己檢測(cè)信號(hào),數(shù)字是隔多少時(shí)間檢測(cè)多少,今天碰巧看到workerman信號(hào)分發(fā)那段代碼,發(fā)現(xiàn)使用了一個(gè)函數(shù)posix_signal_dispatch(),資料說該函數(shù)是:調(diào)用等待信號(hào)的處理器,也摸不著頭緒這個(gè)函數(shù)到底是干嘛的
測(cè)試代碼一:
echo "安裝信號(hào)處理器...\n";
echo "父進(jìn)程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
echo posix_getpid()." 信號(hào)處理器被調(diào)用\n";
});
$pid = pcntl_fork();
if($pid){
//parent
echo "這里是父進(jìn)程".posix_getpid()."\n";
echo "剛剛新建了子進(jìn)程".$pid."\n";
posix_kill($pid, SIGHUP);
}else{
echo "我是子進(jìn)程".posix_getpid()."\n";
}
//pcntl_signal_dispatch();
echo "完成\n";
這段代碼里面我沒有使用declare和pcntl_signal_dispatch,可以發(fā)現(xiàn)處理信號(hào)函數(shù)并沒有被觸發(fā)
測(cè)試代碼二
declare(ticks=1);
echo "安裝信號(hào)處理器...\n";
echo "父進(jìn)程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
echo posix_getpid()." 信號(hào)處理器被調(diào)用\n";
});
$pid = pcntl_fork();
if($pid){
//parent
echo "這里是父進(jìn)程".posix_getpid()."\n";
echo "剛剛新建了子進(jìn)程".$pid."\n";
posix_kill($pid, SIGHUP);
}else{
echo "我是子進(jìn)程".posix_getpid()."\n";
}
echo "完成\n";
發(fā)現(xiàn)信號(hào)檢測(cè)函數(shù)被觸發(fā)了,這就說明declare(ticks=1);確實(shí)可以幫助進(jìn)程檢測(cè)接收到的信號(hào)
但是這個(gè)函數(shù)ticks后面的數(shù)值代表著基礎(chǔ)代碼執(zhí)行了多少次后會(huì)被檢測(cè)一次,基礎(chǔ)代碼是什么,如何檢測(cè),喜歡這塊的可以自己查查
那么如果我們將ticks后面的數(shù)值調(diào)到1000,你就會(huì)發(fā)現(xiàn)信號(hào)又接收不到了,為什么,留給自己思考
測(cè)試代碼三
echo "安裝信號(hào)處理器...\n";
echo "父進(jìn)程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
echo posix_getpid()." 信號(hào)處理器被調(diào)用\n";
});
$pid = pcntl_fork();
if($pid){
//parent
echo "這里是父進(jìn)程".posix_getpid()."\n";
echo "剛剛新建了子進(jìn)程".$pid."\n";
posix_kill($pid, SIGHUP);
}else{
echo "我是子進(jìn)程".posix_getpid()."\n";
}
pcntl_signal_dispatch();
echo "完成\n";
這里發(fā)現(xiàn)信號(hào)觸發(fā)函數(shù)也被觸發(fā)了,因?yàn)檫@個(gè)函數(shù)的作用就是檢測(cè)當(dāng)前進(jìn)程有沒有接收到信號(hào),如果有,就按照信號(hào)處理函數(shù)之前已經(jīng)綁定的處理方法進(jìn)行處理
測(cè)試代碼
echo "安裝信號(hào)處理器...\n";
echo "父進(jìn)程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
echo posix_getpid()." 信號(hào)處理器被調(diào)用\n";
});
$pid = pcntl_fork();
if($pid){
//parent
echo "這里是父進(jìn)程".posix_getpid()."\n";
echo "剛剛新建了子進(jìn)程".$pid."\n";
sleep(1);
posix_kill($pid, SIGHUP);
}else{
echo "我是子進(jìn)程".posix_getpid()."\n";
}
pcntl_signal_dispatch();
sleep(2);
echo "完成\n";
這個(gè)稍微有個(gè)小改動(dòng)就是讓主進(jìn)程睡了一秒,(聽了@walkor的意見)但是在接受消息之后子進(jìn)程和父進(jìn)程都睡兩秒,這樣就排除了子進(jìn)程已經(jīng)結(jié)束,父進(jìn)程發(fā)送信號(hào)沒有接受者
然后再發(fā)送信息,這樣做主進(jìn)程就在子進(jìn)程調(diào)用dispatch函數(shù)之后才發(fā)送了信息,我做這個(gè)主要就是為了驗(yàn)證,dispatch是一個(gè)讓進(jìn)程一直持有的狀態(tài),還是只執(zhí)行一個(gè)動(dòng)作,結(jié)果就是子進(jìn)程沒有接收到信號(hào)
總結(jié)的很好,都正確。
不過子進(jìn)程最好sleep下,因?yàn)橹鬟M(jìn)程運(yùn)行posix_kill($pid, SIGHUP)的時(shí)候,子進(jìn)程可能已經(jīng)退出了
@walkor 請(qǐng)看看這么驗(yàn)證的是否正確