[英]thread_guard vs scoped_thread
在書里
安東尼威廉姆斯的“C ++並發行動”
你可以找到以下兩段代碼(我已經介紹了一些細微的修改):
小片1:
class thread_guard
{
std::thread& t;
public:
explicit thread_guard(std::thread& t_): t(t_){}
~thread_guard()
{
if(t.joinable())
{
t.join();
}
}
thread_guard(thread_guard const&)=delete;
thread_guard& operator=(thread_guard const&)=delete;
};
void my_func()
{
for(int j = 0; j < 1000; ++j)
{
cout << "\n " << j;
}
}
void f()
{
std::thread t1(my_func);
thread_guard g(t1);
do_something_in_current_thread();
}
int main()
{
f();
return 0;
}
繼續你可以找到
摘錄2:
class scoped_thread
{
std::thread t;
public:
explicit scoped_thread(std::thread t_): t(std::move(t_))
{
if(!t.joinable())
throw std::logic_error(“No thread”);
}
~scoped_thread()
{
t.join();
}
scoped_thread(scoped_thread const&)=delete;
scoped_thread& operator=(scoped_thread const&)=delete;
};
void my_func()
{
for(int j = 0; j < 1000; ++j)
{
cout << "\n " << j;
}
}
void f()
{
scoped_thread st1(thread(my_func));
thread t2(my_func);
scoped_thread st2(move(t2));
do_something_in_current_thread();
}
int main()
{
f();
return 0;
}
我不確定我是否真的能夠理解這2個片段之間的真正區別。
我可以看到的唯一區別是,在Snippet 1中, thread_guard
的實例不占用線程t1
所有權(與scoped_thread
對象不同),因此可以調用t1.join()
但這不是問題~thread_guard()
被執行。
那么:Snippet 2的優勢在哪里(如果存在)?
這兩種類型都意味着在線程完成之前阻止破壞(例如范圍退出)。 不同之處在於thread
對象的所有權。
thread_guard
不擁有該thread
本身; 可能有多個thread_guard
在同一個thread
上等待。 這也意味着只要thread_guard
引用它, thread
對象就必須是活動的。 如果在銷毀thread_guard
對象時已經連接了引用的線程,它將不會阻塞或產生錯誤(而不是僅在不可連接的線程上調用join
)。
另一方面, scoped_thread
獲取thread
實例的所有權,因此也控制其生命周期。 只要您想擁有想要等待的線程,就可以使用它,例如作為數據成員。
最終,你使用的是一個語義問題:你想等待別人擁有的線程(然后你還必須確保沒有生命周期問題),或者你想要一個thread
對象阻塞它的時候被摧毀,沒有你必須先join
它。
在功能方面,這兩個實現都能夠服務於目的,我在這兩個實現中可以看到的唯一區別是, Snippet 2
可以接受lvalue(glvalue)
和rvalue(prvalue)
但Snippet 1
不能接受rvalue(prvalue)
作為構造函數參數。 例如,考慮以下代碼,
std::thread getThread()
{
return std::thread([](){ std::cout<< __PRETTY_FUNCTION__<< std::endl;});
}
int main( int , char *[])
{
thread_guard g( getThread());
return 0;
}
現在,如果您編譯此代碼,編譯將給出以下錯誤,
error: cannot bind non-const lvalue reference of type ‘std::thread&’ to an rvalue of type ‘std::remove_reference<std::thread&>::type’ {aka ‘std::thread’}
explicit thread_guard(std::thread _t): t(std::move( _t)){ std::cout<< __PRETTY_FUNCTION__<< std::endl;}
但是, snippet 2
實現將正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.