我非常想了解Eric Niebler關于 c 期貨和懸空本地參考的警告(在標題為“執行緒問題”的部分)。因此,我寫了一個小程式,重復如下:
#include <iostream>
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
void computeResult(int& i) {
boost::this_thread::sleep_for(boost::chrono::seconds(1));
std::cout << i << std::endl;
i = 1;
}
boost::future<int> doThing() {
int local_state{0};
auto lam = [&]() { return computeResult(local_state); };
auto fut = boost::async(lam);
return fut.then([&](auto&&) { return local_state; }); // OOPS
}
int main() {
auto fun = doThing();
int out = fun.get();
std::cout << out << std::endl;
}
案文指出:
如果你以前用過期貨編程,你可能會尖叫,“Nooooo!” 最后一行的 .then() 將一些作業排??入佇列,以便在 computeResult() 完成后運行。doThing() 然后回傳結果未來。問題是,當 doThing() 回傳時,State 物件的生命周期結束,并且延續仍然參考它。這現在是一個懸空參考,并且可能會導致崩潰。
我doThing稍微修改了該函式以computeResult異步呼叫,但其他方式嘗試遵循文本中的示例。不幸的是,該程式在我的計算機上運行得非常好。有人可以概述如何撰寫一個可靠崩潰的程式,如 Eric Niebler 的描述中所述嗎?
uj5u.com熱心網友回復:
就像每個人都說的那樣,相信未定義行為會導致崩潰是錯誤的。
這是一個危險的信念,因為當出現靜默資料損壞、死鎖或多年來確實沒有任何容易觀察到的情況(直到您的程式突然發射核導彈)時,UB 的后果要可怕得多。
有一些工具(如 asan/ubsan 和 valgrind/helgrind)可以在許多案例給您帶來更多痛苦之前對其進行診斷。
讓我們使用 GCC 或 Clang 的-fsanitize=address,undefined選項運行您的示例:
1264
AddressSanitizerAddressSanitizer:DEADLYSIGNAL
:DEADLYSIGNAL
=================================================================
==13854==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7fc8d475b88e bp 0x613000000040 sp 0x7fc8c4cfe9b0 T1)
==13854==The signal is caused by a READ memory access.
==13854==Hint: this fault was caused by a dereference of a high value address (see register values below). Dissassemble the provided pc to learn which register was used.
/home/sehe/custom/boost_1_77_0/boost/thread/lock_types.hpp:346:14: runtime error: member call on misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/pthread/mutex.hpp:61:48: runtime error: member access within misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/lock_types.hpp:331:18: runtime error: member call on misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 01 00 00 00 00 00 00 00 1e 36 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
/home/sehe/custom/boost_1_77_0/boost/thread/pthread/mutex.hpp:70:13: runtime error: member access within misaligned address 0x6120000004f1 for type 'struct mutex', which requires 8 byte alignment
0x6120000004f1: note: pointer points here
00 00 00 00 01 00 00 00 00 00 00 00 1e 36 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
1265
(作為旁注,即使沒有消毒劑,給定的程式也會導致我的機器/編譯器崩潰)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/344601.html
上一篇:Files.copy是Java中的執行緒安全函式嗎?
下一篇:對json資料使用異步的最佳實踐
