2013-06-03 2 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-references hash, thread::idget_id이 잘 작동합니다.

만이 라인의 메신저 ID로 점점 항상 0 (영)

ID가 해시 행 아래에 다음 줄을 추가하면 작동하고 내가 스레드에서 해시 ID를 얻을 : std::thread::id tid = std::this_thread::get_id(); 심지어 내가 해달라고 tid

누군가가이 동작을 설명 할 수 있습니까? 메신저 이클립스 주노와 협력 프로젝트를 여러 번 다시 + 청소 ... 난 그냥 그것을 얻을 해달라고 : 여기/

코드 : 여기 형식 규칙이 바보이기 때문에 라인으로 (라인 -.-

%ldlong 아닌 double, 그래서 프로그램이 동작을 정의되지 않은 것처럼
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

, 그래서 컴파일러는 부동 소수점 레지스터에 test을두고 함수를 호출합니다. printf 구현은 "%ld" 변환 지정자가 long int 인수를 예상한다고 알려주기 때문에 비 부동 소수점 레지스터에서 인수를 찾습니다. 실제 인수가 printf과 동일한 레지스터에 없기 때문에 값을 찾지 못합니다.

다음 줄을 추가하면 tid의 값이 비 부동 소수점 레지스터에 포함되며 분명히 printf이이를 찾을 수 있습니다 (그러나 의존하지는 않지만 정의되지 않은 동작이며 예측할 수 없습니다).

해결책 : printf을 올바르게 사용할 수 없으면 전혀 사용하지 마십시오. double에 지정된 올바른 전환 (예 : "%f")을 사용하거나 값을 다른 유형으로 저장하거나 iostreams를 사용하십시오.

+0

관찰 된 동작을 일으킬 수있는 +1 훌륭한 설명. – ComicSansMS

2

형식 지정자이 잘못 또한, std::hash<>::operator()의 반환 값 유형이 size_t하지 double입니다 대신 (안전 형) std::cout 사용합니다..

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

출력이 잘못되었습니다. %ddouble이 아니며, 십진수, 즉 int 초를 나타냅니다. 당신이 원하는 무엇

방금 ​​처음에 std::cout를 사용한 경우 hmjd의 대답에 의해 제안 물론

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

는이 중 어느 것도, 일어나지 않았을 것입니다. 당신이 printf("%ld\n", test)를 호출 할 때 printfdouble 인수가 long 인수에 다른 레지스터에 전달 될 x86_64의에

+0

% ld는 사실 내가 원하는 것입니다. gdb에서 출력은 입니다. [새 스레드 0x7ffff308f700 (LWP 20234)] 16 진수 값은 ID입니다. 만약 내가 이것을 % f로 인쇄한다면 그 값은 같지 않은가? 아니면 혼란 스럽습니까? – baam

+3

그러면 해시를 처음에 이중으로 저장하는 이유는 무엇입니까? 방금'std :: hash'의 원래 리턴 유형 인'size_t'를 남겼습니다. – ComicSansMS

+0

@baam, 혼란스러워합니다. 만약 당신이'printf'에'double'을 건네 주면''% f "'를 사용하여 double을 넘겨 준다고 말해야합니다 ... 사실 그것이"실제로 당신이 원하는 것 "이 아닌지 (또는 당신이 원한다고 생각하는 것). 잘못해서 정의되지 않은 행동을하기 때문입니다. 16 진수 값을 원한다면''% ld "'_or_'"% f "'를 원하지 않습니다. 둘 다 16 진수 값을 출력하지 않기 때문입니다! 'printf'를 올바르게 사용할 수 없다면, 전혀 사용하지 마십시오. –