簡體   English   中英

thread_guard vs scoped_thread

[英]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.

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