有什么辦法可以防止主執行緒崩潰?
我希望主執行緒在此記憶體訪問沖突例外發生后繼續運行。
std::thread {
[]() {
for (auto i = 0; i < 10; i) {
std::cout << "Hello World from detached thread!\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
std::cout << "Boom!\n";
*(int*)(0) = 42;
}
}.detach();
while (true) {
std::cout << "Hello World!\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
uj5u.com熱心網友回復:
一般不會。
訪問沖突的一個主要原因是記憶體損壞 - 指向資料元素的指標被覆寫,或者某些物件的大小被擦除。一個行程中只有一個記憶體地址空間。最有可能發生這種情況的地方之一是在由new、malloc()、等人分發的記憶體堆中。每個行程只有一個堆。
因此,任何破壞記憶體的執行緒都會破壞所有執行緒的記憶體。
請注意,在您設計的示例中,您知道您正在延遲空指標。實際代碼中的問題是您永遠不會知道為什么要取消參考空指標。如果您非法訪問的記憶體不在地址 0 或與它非常接近的某個值,則某些“殺死該執行緒以便其余執行緒可以生存”邏輯永遠無法真正知道發生了什么。
你可以試著繼續奔跑,就像你可以試著穿過雷區一樣。
如果你繼續跑步,你怎么知道你的結果是有效的?您幾乎肯定永遠不會測驗過您的行程試圖運行的任何確切的記憶體損壞。因為如果你知道,你就會知道那個錯誤并修復它,對嗎?
如果你的執行緒在持有某種鎖的時候死了,你會怎么做?
uj5u.com熱心網友回復:
您可以使用sigaction為 SIGSEGV 安裝一個處理程式,使該執行緒在 main 保持運行時保持忙碌。
static void handler(int sig, siginfo_t* si, void* unused)
{
sleep(100000); // or something similar that's async-signal-safe
// on your operating system
}
int main(int argc, char *argv[])
{
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
perror("sigaction");
...
這當然是難以置信的脆弱。例如,如果生成 SIGSEGV 的執行緒持有一個鎖,那么它不會被釋放以便其他執行緒可以獲取它。
正如 Ulrich 指出的那樣,容忍這些事情的通常方法是產生子行程。眾所周知,谷歌瀏覽器早在幾年前就開始為它的瀏覽器標簽做這件事,幫助它比當時的其他瀏覽器具有更高的彈性(然后他們不得不趕上自己)。現代作業系統使擁有多個行程變得非常高效,而在較舊的作業系統中,執行緒可能使用了大量更少的資源......
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/330288.html
上一篇:Ionic使模型中的一個欄位的型別成為其他兩個模型的選擇
下一篇:帶有改造的協程執行緒安全
