簡體   English   中英

中斷多個線程上的系統調用

[英]Interrupt system calls on multiple threads

我有一堆 pthreads,每個都阻塞一個系統調用,例如recv()wait()

我想在信號到達時中斷它們(並讓它們返回 errno = EINTR ),所以我使用沒有SA_RESTARTsigaction()來設置中斷處理程序。 最終目標是優雅地退出整個程序。

然而,似乎只有處理信號的線程被中斷,而其他線程繼續阻塞它們的系統調用。

我如何打斷他們所有人?

signal(7) -s 對pthreads(7)不友好(在 Linux 上使用clone(2)實現)

考慮(像Qt一樣)在每個線程中都有一些事件循環,並使用signalfd(2) 它與poll(2)兼容,因此與socket(7)兼容。

或者,設置一些全局volatile sigatomic_t flag; 在您的信號處理程序中,並在每個線程中測試該標志。 另見<stdatomic.h>

請注意延續傳遞風格范式。

為了中斷所有線程,您需要使用pthread_kill分別向它們發出信號,而不是向進程發出信號,這意味着您需要保留可能要發出信號的線程列表。 請注意,由於信號總是有可能在阻塞系統調用之前的最后一次檢查之后到達,但在實際進行系統調用之前,總是需要重復發出信號(帶有適當的退避),直到發出信號的線程以某種方式響應以指示它已接受中斷請求。 這是原始信號中斷概念中固有的競爭條件,即使沒有線程也是如此。

如果您的意圖是線程在中斷它們阻塞的系統調用后不久終止,您可以使用線程取消而不是信號。 這不需要處理EINTR的問題(上述競爭條件等),但確實需要圍繞取消的可能性來構建您的代碼。 這意味着根據執行的代碼是否准備好處理它來啟用/禁用取消,並設置取消處理程序以適當地取消任何不一致的 state、釋放資源、釋放鎖等。

如果您確實使用信號,則volatile sigatomic_t對象不應在解決方案中發揮任何作用。 信號處理程序可以而且應該是一個完全空的 function; 它的唯一目的是引起EINTR 信號線程和信號線程應該通過標准的 pthread 同步原語(互斥體,可能的條件變量和/或信號量)進行通信,以指示請求中止操作並確認對請求的操作。

暫無
暫無

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

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