在以下程式中,在一個執行緒 (main) 正在執行期間thread::join,另一個執行緒 (x) 呼叫thread::detach:
#include <thread>
#include <iostream>
int main(void) {
auto t = std::thread([] {
std::this_thread::sleep_for( std::chrono::milliseconds(1000) );
} );
auto x = std::thread([&t] {
std::this_thread::sleep_for( std::chrono::milliseconds(500) );
if ( t.joinable() )
{
std::cout << "detaching t..." << std::endl;
t.detach();
}
} );
std::cout << "joining t..." << std::endl;
t.join();
x.join();
std::cout << "Ok" << std::endl;
return 0;
}
它在 GCClibstdc 和 Clang 的libc 列印中作業正常
joining t...
detaching t...
Ok
但在 Visual Studio 中,程式在列印之前以非零退出代碼終止Ok。在線演示:https ://gcc.godbolt.org/z/v1nEfaP7a
它是 Visual Studio 中的錯誤還是程式包含一些未定義的行為?
uj5u.com熱心網友回復:
既不join是也不detach是const-qualified,因此允許實作修改thread物件的內部記憶體,而不必根據默認資料競爭避免要求對這些成員函式的非同步呼叫提供任何寫入/寫入或寫入/讀取資料競爭避免的保證[res.on.data.races]。
在 [thread.threads] 或其他任何地方提到的這些功能的這條規則也沒有例外。
因此,在兩個呼叫join之間detach沒有建立happens-before關系的呼叫是一種資料競爭,會導致未定義的行為。
即使沒有呼叫,在/對呼叫detach上仍然存在寫入/讀取資料競爭。joinjoinable
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/520375.html
標籤:C 多线程语言律师
上一篇:在C中使用信號量進行數學運算
下一篇:將Volatile.Read與Interlocked.Exchange結合使用以從.NET中的多個執行緒同時訪問共享記憶體位置是否安全?
