2017-04-26 44 views
7

考慮下面的情況在新線程中訪問移動的std :: string

將名稱字符串作爲參數移動到線程。

void start(std::string&& name) { 
     t = std::thread{&ThreadRunner::run, this, std::forward<std::string>(name)}; 
    } 

該線程的運行函數也需要一個右值引用。

void run(std::string&& name) { 
     const auto errnum = pthread_setname_np(t.native_handle(), name.c_str()); 
     if (errnum != 0) { 
      std::cout << "ERROR " << std::endl; 
     } 
    } 

線程通過如下開始函數創建:

ThreadRunner r; 
    r.start(std::string("somename")); 

的問題是。通過pthread_setname_np在函數run中訪問的std :: string可能是垃圾的,因爲在範圍結束時臨時超出了範圍?

Demo 在上面的演示中,call結束之後,它存在保證了somename字符串是在功能run有效?

編輯: Demo with constructors/destructors 的的std :: string的問題是現在有Wrap更換打印所涉及的構造函數。

結果是:(第二字段是對象的地址,第三個是線程id)

Constructed 0x7ffc395e0ef0 140605000369984 
Move Constructed 0x7ffc395e0e60 140605000369984 
Move Constructed 0x177a0a0 140605000369984 
Destroyed 0x7ffc395e0e60 140605000369984 
Destroyed 0x7ffc395e0ef0 140605000369984 
Call ended 

somename 
Destroyed 0x177a0a0 140604983461632 

的最後一個對象,之後run端部銷燬。它是否仍然指暫時的。我想不是。

A more clean example

編輯: 的意見後,這個問題歸結爲

「後,原來的呼叫爲void開始(的std :: string & &名);已經 返回後std :: thread的構造函數已結束,其中是 void run(std :: string & & name)的字符串;正在處理?「

最新的演示代碼似乎表明run引用的對象Wraprun退出後被破壞。

+7

不要濫用'std :: forward'來處理它沒有提供的作業,請使用'std :: move'。 – Rakete1111

+0

@ Rakete1111注意。謝謝。 – themagicalyang

回答

0

沒有懸掛參考,因爲std::thread的構造函數參數被客戶端線程複製/移動到某個結構中。新創建的線程將在此結構中的複製/移動對象上運行。

在您的具體情況下,std::string對象確實已移入所描述的結構中。這是std::string對象run()正在進行中。當線程完成執行時它將被正確銷燬。