簡體   English   中英

POSIX線程和信號

[英]POSIX threads and signals

我一直在努力理解POSIX線程和POSIX信號如何相互作用的復雜性。 特別是,我對以下內容感興趣:

  • 什么是控制信號傳遞到哪個線程的最佳方法(假設它首先不是致命的)?
  • 告訴另一個線程(可能實際上很忙)信號已經到達的最佳方法是什么? (我已經知道從信號處理程序使用pthread條件變量是一個壞主意。)
  • 如何安全地處理將信號發生的信息傳遞給其他線程? 這是否需要在信號處理程序中發生? (我一般不想殺死其他線程;我需要一個更微妙的方法。)

關於我為什么要這樣做的參考,我正在研究如何將TclX包轉換為支持線程,或者將其拆分並至少使一些有用的部分支持線程。 信號是特別感興趣的部分之一。

  • 什么是控制信號傳遞到哪個線程的最佳方法?

正如@ zoli2k所指出的那樣,明確地指定一個線程來處理你想要處理的所有信號(或者每個具有特定信號職責的一組線程),這是一種很好的技術。

  • 告訴另一個線程(可能實際上很忙)信號已經到達的最佳方法是什么?[...]
  • 如何安全地處理將信號發生的信息傳遞給其他線程? 這是否需要在信號處理程序中發生?

我不會說“最好”,但這是我的建議:

main阻止所有所需信號,以便所有線程都繼承該信號掩碼。 然后,將特殊信號接收線程設計為信號驅動事件循環,將新到達的信號作為一些其他線程內通信進行分派。

最簡單的方法是讓線程使用sigwaitinfosigtimedwait在循環中接受信號。 然后線程以某種方式轉換信號,可能廣播pthread_cond_t ,喚醒具有更多I / O的其他線程,在特定於應用程序的線程安全隊列中排隊命令,無論如何。

或者,特殊線程可以允許將信號傳遞到信號處理程序,僅在准備好處理信號時取消屏蔽以便傳送。 (然而,通過處理程序傳遞信號往往比通過sigwait系列接收信號更容易出錯。)在這種情況下,接收器的信號處理程序執行一些簡單且異步信號安全的操作:設置sig_atomic_t標志,調用sigaddset(&signals_i_have_seen_recently, latest_sig)write一個字節write一個非阻塞的自管道等等。然后,回到其屏蔽的主循環中,線程將信號的接收傳遞給其他線程,如上所述。

更新 @caf正確地指出sigwait方法是優越的。)

根據POSIX標准,所有線程應該在系統上顯示相同的PID,並且使用pthread_sigmask()可以為每個線程定義信號阻塞掩碼。

由於允許每個PID只定義一個信號處理程序,我更喜歡處理一個線程中的所有信號,如果需要取消正在運行的線程,則發送pthread_cancel() 它是針對pthread_kill()的首選方法,因為它允許為線程定​​義清理函數。

在一些較舊的系統上,由於缺乏適當的內核支持,正在運行的線程可能與父線程的PID具有不同的PID。 有關在Linux 2.4上使用linuxThreads進行信號處理的常見問題解答。

恕我直言,Unix V信號和posix線程混合不好。 Unix V是1970.POSIX是1980;)

有取消點,如果你在一個應用程序中允許信號和pthreads,你最終會在每個調用周圍編寫循環,這可能會令人驚訝地返回EINTR。

所以我在(少數)我需要在Linux或QNX上編程多線程的情況下做的是,屏蔽所有(但是一個)線程的所有信號。

當Unix V信號到達時,進程切換堆棧(這是Unix V中的並發性,就像在進程中一樣)。

正如這里提到的其他帖子所暗示的,現在可能告訴系統哪個posix線程應該是該堆棧切換的受害者。

有一次,你設法讓你的信號處理程序線程工作,問題仍然存在,如何將信號信息轉換為文明的東西,其他線程可以使用。 需要用於線程間通信的基礎結構。 一種模式,有用的是actor模式,其中每個線程都是某些進程內Messaging機制的目標。

因此,您應該嘗試將信號從Signal上下文編組到Signal處理程序線程,然后使用actor模式通信機制向這些actor發送語義上有用的消息,而不是取消其他線程或殺死它們(或其他奇怪的東西),誰需要信號相關的信息。

到目前為止我在哪里:

  • 信號來自不同的主要類別,其中一些通常應該只是殺死進程(SIGILL),其中一些從不需要做任何事情(SIGIO;更容易直接做異步IO)。 這兩個類不需要任何操作。
  • 有些信號不需要立即處理; 像SIGWINCH這樣的人可以排隊等候直到方便(就像來自X11的事件)。
  • 棘手的是你想要通過打斷你正在做的事情來回應它們但沒有達到消除線程的程度。 特別是,交互模式下的SIGINT應該保持響應。

我仍然需要對signalsigactionpselectsigwaitsigaltstack以及一大堆其他POSIX(和非POSIX)API進行排序。

暫無
暫無

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

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