我寫我正在開發一個Linux發行版系統關鍵程序。它需要在接收到某些信號時重新啓動,以儘量避免崩潰。問題是,重新啓動後,我無法重新啓用該信號。也就是說,信號不能被接收兩次。在execv()自己完成之後,當新進程調用signal()來設置信號時,SIG_DFL被返回。每次。即使我連續兩次調用它 - 表明它從來沒有設置在第一位。是否有一些奇怪的國旗從原始過程中遺留下來?信號不正確跨越execv重新啓用()
3
A
回答
8
您正在下降的事實,你基本上是試圖遞歸處理的信號犯規。
當使用signal()
註冊信號處理程序時,該信號編號被阻塞,直到信號處理程序返回 - 實際上,在調用信號處理程序時,內核/ libc塊會發出信號,並在信號處理程序返回後解除阻塞。因爲你永遠不會從信號處理程序返回(而不是你execl
一個新的二進制),SIGUSR1
保持阻塞,所以不會被第二次捕獲。
這可以通過之前,你發送的第一SIGUSR1
後檢查/proc/</pid>/status
可以看出。
前:
$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000000
SigCgt: 0000000000000200
後:
$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000200
SigCgt: 0000000000000200
注意SigCgt
指示信號10註冊(號碼是位字段;第10位,這相當於SIGUSR1,看到man signal(7)
爲號碼)。 SigBlk
之前,你的進程,但它發送包含SIGUSR1
信號後發送SIGUSR
是空的。
你有兩種方法可以解決這個問題:
a)。在sighandler
調用execl
之前,手動解鎖SIGUSR
:
sigset_t sigs;
sigprocmask(0, 0, &sigs);
sigdelset(&sigs, SIGUSR1);
sigprocmask(SIG_SETMASK, &sigs);
B)。使用sigaction
與SA_NODEFER
標誌,而不是signal
註冊信號處理程序。這將防止SIGUSR1
被擋住了信號處理函數中:
struct sigaction act;
act.sa_handler = signalhandler;
act.sa_mask = 0;
act.sa_flags = SA_NODEFER;
sigaction(SIGUSR1, &act, 0);
1
信號處理不跨越exec
因爲exec
將覆蓋整個地址空間繼承,而不是重置任何信號處理程序將被指向了錯誤的地方。它不是重置的唯一情況是,如果它被設置爲,比方說,SIG_IGN
,這是不依賴於預exec
進程的地址空間。
相關問題
- 1. 跨越重啓不會持續
- 2. 跨度ID越來越不確定
- 3. 跨多個EJB跨越用戶信息
- 4. 短信號碼不正確?
- 5. 重新啓動循環與信號
- 6. 正確使用PyQt信號
- 7. jQuery UI的亮點DIV不包含子跨越正確
- 8. 在qt4中跨類傳遞信號的正確方法?
- 9. 彪馬將不會重新啓動一個SIGUSR1信號
- 10. 按鈕信號檢測不正確
- 11. 呈現跨越重定向
- 12. 越來越多的信號手柄
- 13. 的WebView在Honycomb越來越信號11
- 14. Selection.setSelection不能跨越
- 15. 創建新跨越的標籤爲他人跨越
- 16. 如何正確使用信號燈
- 17. 重新啓動手機越來越多通知的
- 18. 跨越
- 19. 重新啓用Paymill訂閱,並更新信用卡信息
- 20. 使用多層信號從線程更新QML是否正確?
- 21. GtkWave不是從IVerilog模擬信號越來越
- 22. 不從燒瓶安全越來越信號
- 23. 越來越不正確得分使用SentiWordNet
- 24. C#延遲(異步)執行跨越重啓
- 25. Spring Batch的重新啓動 - 不拿起正確的行
- 26. 勾號標籤跨越多行
- 27. 暗號 - 跨越同一標籤
- 28. 表格單元格沒有正確地跨越
- 29. 如何創建正確跨越多頁的可打印列表
- 30. 如何正確創建跨越多個頁面的HTML表單
這就是我想。我所說的是,在執行完成後,新進程不能再次設置信號 - 而不是繼續執行。無論我做什麼,在從信號處理程序執行完一個進程之後,我都不能再設置相同的信號。 – c4757p 2009-06-21 14:32:45
你有一些我可以測試的代碼嗎?我現在對此很好奇。 – 2009-06-21 14:40:30