簡體   English   中英

如何匿名聲明std :: thread?

[英]How can I declare an std::thread anonymously?

考慮以下簡短程序:

#include <thread>

int Foo() {
while (1);
}

int main(){
    std::thread t(Foo);
    std::thread s(Foo);

    // (std::thread(Foo));

    t.join();
}

這編譯和運行(永遠),與

g++ -Wl,--no-as-needed DoubleBufferTest.cc -o DoubleBufferTest -std=c++0x -pthread

在注釋掉的行中,我試圖使用此處描述的技術匿名聲明一個新線程。 但是,當該行被注釋回來時,我可以編譯但運行時會出現以下錯誤:

terminate called without an active exception            
Aborted (core dumped)                                   

我怎樣才能正確地匿名聲明一個帖子?

注意,我在g++ 4.4.7

如果線程尚未加入或分離, std::thread的析構函數將調用std::terminate

所以很遺憾你不能像這樣創建一個匿名線程對象 - 你需要引用thread對象才能調用join()detach()

Scott Meyers在2013年的Going Native上發表了一篇演講,他創建了一個包含線程的RAII類,並在析構函數中調用join。 你可以做類似的事情:

class ThreadRAII {
public:
  ThreadRAII(std::thread&& thread): t(std::move(thread)) {}
  ~ThreadRAII() { if (t.joinable()) { t.join(); }

private:
  std::thread t;
};

見他的博客文章談話的更多信息。

你可以像這樣使用它

(ThreadRAII(std::thread(Foo)));

但是,您希望以這種方式創建線程的唯一原因是,如果您不關心它何時(或如果)結束,那么在這種情況下,連接沒有多大意義。 您應該修改析構函數以分離:

~ThreadRAII() { if (t.joinable()) { t.detach(); }

正如評論中所建議的那樣,通過完美轉發到構造中的內部線程,您可以更容易地使用它:

class ThreadRAII2 {
public:    

    template <typename Func, typename ...Args>
    explicit ThreadRAII2(Func&& func, Args&&... args) :
        t(func, std::forward<Args>(args)...) {  }

    ~ThreadRAII2() { 
        if (t.joinable()) t.detach(); 
    }
private:
    std::thread t;
};

然后你可以像你原來想的那樣使用它,不需要分離:

(ThreadRAII2(Foo));

或者,如果Foo接受參數(例如Foo(int) ):

(ThreadRAII2(Foo, 42));

你可以這樣做:

std::thread(Foo).detach();

我不認為這(你所指的技術)是可能的線程。

看看這里;

30.3.1.3 thread析構函數[thread.thread.destr]

〜螺紋();

如果joinable()然后terminate(),否則沒有效果。 [注意:在析構函數中隱式分離或連接joinable()線程可能導致難以調試正確性(用於分離)或性能(用於連接)僅在引發異常時遇到的錯誤。 因此,程序員必須確保在線程仍可連接時永遠不會執行析構函數。 - 結束說明]

基本上,當執行繼續執行違反上述規則的下一行時,您正在創建的臨時匿名對象(即線程)被破壞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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