2013-06-03 97 views
1

我需要根據需要創建一些線程,因爲我不前我是多麼需要知道的。 要「存儲」線程即時通訊使用矢量std::vector<std::thread> threads; 每次我創建一個新的線程時間我把它們放回在載體:threads.push_back(std::thread(worker));標準C++線程ID - 奇怪的行爲

存儲(用於測試)線程ID我用下面的:根據double test = std::hash<std::thread::id>()(std::this_thread::get_id()); 到CPP參考hashthread::idget_id這應該工作正常。

但只此行即時得到的ID總是0(零)

如果ID添加散列線之下以下行它的工作原理,我從線程得到一個散列ID:std::thread::id tid = std::this_thread::get_id(); 即使我不使用tid

有人可以解釋這種現象? IM與Eclipse JUNO合作和清洗+重建項目幾次......我只是不明白:/

這裏的代碼: (用線,因爲這裏的格式規則是愚蠢線-.-

std::vector<std::thread> threads; 
void worker(){ 
    double test = std::hash<std::thread::id>()(std::this_thread::get_id()); 
    std::thread::id tid = std::this_thread::get_id(); 
    printf("%ld\n", test); 
} 
void joinThreads(std::thread& t) 
{ 
    t.join(); 
} 
int main() { 
    for (int i = 0; i < 10; ++i) { 
     threads.push_back(std::thread(worker)); 
    } 
    std::for_each(threads.begin(),threads.end(),joinThreads); 
    return 0; 
} 
+1

發佈編碼? –

+0

代碼被添加..花了一段時間,因爲我總是得到「錯誤」格式的錯誤Oo – baam

回答

5

在x86_64一個double參數printf將在不同的寄存器傳遞給long參數,所以當你調用printf("%ld\n", test)編譯器把test在浮點寄存器和調用函數。然後printf實現查找參數在非浮點寄存器,因爲"%ld"轉換符告訴它期望long int說法。由於實際參數與printf看起來不在同一個寄存器中,因此無法找到該值。

當您添加它引起的tid值是在非浮點寄存器中的下一行,顯然,讓printf找到它(但不依賴於,它是不確定的行爲和不可預知的。)

解決方法:如果你不能正確使用printf那麼就不要使用它。要麼使用double指定的正確轉換,即"%f",要麼將值存儲在不同類型中,要麼使用iostream。

+0

+1什麼可能導致觀察到的行爲的優秀解釋。 – ComicSansMS

2

格式說明是不正確的%ldlong,不是double,所以該方案不確定的行爲同樣,std::hash<>::operator()返回值的類型是size_t,不double使用(類型安全)std::cout代替:。

auto test = std::hash<std::thread::id>()(std::this_thread::get_id()); 
std::cout << test << std::endl; 
2

你的輸出是錯誤的。 %d不是double,它代表小數,即int秒。

你想要的是

printf("%f\n", test); 

當然,所有這本來如果你只是擺在首位使用std::cout,正巧hmjd的答案的建議。

+0

%ld實際上是我想要的。 in gdb的輸出是 '[New Thread 0x7ffff308f700(LWP 20234)]' 十六進制值就是id。如果我打印這與%F不同的價值? 還是我只是困惑? – baam

+3

那麼爲什麼把哈希首先保存到雙精度?可以留下一個'size_t',它是'std :: hash'的原始返回類型。 – ComicSansMS

+0

@baam,你很困惑。如果你向'printf'傳遞一個'double',你必須告訴它你使用''%f「'來傳遞一個double ......如果這不是」實際上你想要的「(或者認爲你想),因爲你做錯了,導致了未定義的行爲。如果你想要一個十六進制值,那麼你不需要''%ld''或_'「%f」',因爲它們都不打印十六進制值!如果你不能正確使用'printf',那麼請不要使用它。 –