簡體   English   中英

信號安全使用sem_wait()/ sem_post()

[英]Signal safe use of sem_wait()/sem_post()

我試圖在Linux上創建一個包裝器,它控制一次允許多少次並發執行。 為此,我使用系統范圍的計數信號量。 我創建信號量,執行sem_wait() ,啟動子進程,然后在子進程終止時執行sem_post() 那樣就好。

問題是如何安全地處理發送給這個包裝器的信號。 如果它沒有捕獲信號,則命令可能會在不執行sem_post()情況下終止,從而導致信號量計數永久減少1。 所以,我創建了一個執行sem_post()的信號處理程序。 但是,仍有一個問題。

如果在執行sem_wait()之前附加了處理程序,則信號可能在sem_wait()完成之前到達,從而導致sem_post()在沒有sem_wait()情況下發生。 如果我在設置信號處理程序之前執行sem_wait() ,則可以sem_wait()

顯而易見的下一步是在處理程序和sem_wait()的設置期間阻止信號。 這是我現在擁有的偽代碼:

void handler(int sig)
{
  sem_post(sem);
  exit(1);
}

...
sigprocmask(...);   /* Block signals */
sigaction(...);     /* Set signal handler */
sem_wait(sem);
sigprocmask(...);   /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);

現在的問題是sem_wait()可以阻塞,在此期間,信號被阻塞。 試圖殺死進程的用戶可能最終訴諸“kill -9”,這是我不想鼓勵的行為,因為無論如何我都無法處理這種情況。 我可以使用sem_trywait()一小段時間並測試sigpending()但這會影響公平性,因為不再保證等待信號量最長的進程將在下一次運行。

這里有一個真正安全的解決方案,允許我在信號量采集期間處理信號嗎? 我正在考慮求助於“我有信號量”全局並消除信號阻塞,但這不是100%安全,因為獲取信號量並設置全局不是原子的,但可能比等待時阻塞信號更好。

你確定sem_wait()導致信號被阻止嗎? 我不認為是這種情況。 sem_wait()手冊頁說如果它被信號中斷,則從sem_wait()返回EINTR錯誤代碼。

您應該能夠處理此錯誤代碼,然后您的信號將被接收。 您是否遇到未收到信號的情況?

我會確保你處理sem_wait()可以返回的錯誤代碼。 雖然可能很少見,但如果你想100%確定你想要100%的基數。

我知道這已經過時了,但為了那些仍在閱讀Google禮貌的人的利益......

這個問題的最簡單(也是唯一的)穩健解決方案是使用System V信號量,它允許客戶端以一種內核自動返回的方式獲取信號量資源。無論過程如何排除。

你確定你正確地接近了這個問題嗎? 如果要等待子進程終止,可能需要使用waitpid()系統調用。 正如您所觀察到的,如果孩子可能接收到信號,那么期望孩子做sem_post()是不可靠的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM