2015-01-10 6 views
2

제 질문은 꽤 간단합니다. 나는 값의 벡터를 가지고 있으며 (무관 한 스레드들), 나는 그들을 반복하고 싶다. 그러나 나에게 똑같이 보이는 두 가지 버전의 코드가 있지만 두 번째 버전 만 작동합니다. 나는 이유를 알고 싶다.C++ 괄호로 역 참조 (반복자 사용)

버전 1

int main(){ 
    int someValue = 5; 
    vector<std::thread *> threadVector; 

    threadVector.resize(20); 

    for (int i = 0; i < 20; i++) { 
     threadVector[i] = new std::thread(foo, std::ref(someValue)); 
    } 

    for (std::vector<std::thread *>::iterator it = threadVector.begin(); it != threadVector.end(); ++it) { 
     *it->join(); // *********Notice this Line********* 
    } 

    system("pause"); // I know I shouldn't be using this 
} 

버전 (컴파일되지 않음) 2 (합니까 작업)이이 작업의 순서에 문제가있다

int main(){ 
    int someValue = 5; 
    vector<std::thread *> threadVector; 

    threadVector.resize(20); 

    for (int i = 0; i < 20; i++) { 
     threadVector[i] = new std::thread(foo, std::ref(someValue)); 
    } 

    for (std::vector<std::thread *>::iterator it = threadVector.begin(); it != threadVector.end(); ++it) { 
     (*it)->join(); // *********Notice this Line********* 
    } 

    system("pause"); // I know I shouldn't be using this 
} 
+1

'system ("pause")'을 사용하는 것뿐만 아니라 그 문제를 알고 있지만이 무관 한 코드를 게시하는 것은 개선의 여지가 있습니다. ;) 즉, 나는 std :: thread가 움직일 수 있고 컨테이너 (예 : 초기 boost :: thread가 아닌)에 저장할 수 있다고 생각한다. 내가 C++ 11을 가지고 놀지 않았기 때문에 나는 그렇게 많이 잘못 알았을 것이다. –

+0

벡터 안에 무엇이 저장되어 있는지 설명해 주시겠습니까? 나는 unique_ptr을 선언하고 std ::를 벡터로 옮길 수 있다는 것을 의미한다. 그러나 새로운 문장과 다른 점은 무엇인가? – JohnJohn

+0

내가 제안하는 것은 포인터와 동적 할당을 전혀 사용하지 않고 모든 예외 안전 문제와 다른 오버 헤드에 대해 제시 한 것입니다. 마찬가지로 '벡터 '을 사용하지 않고 '벡터 '을 사용 하시겠습니까? 아니면? 나는이 경우에 당신이 정말로 그것을 피할 수 있는지 잘 모르겠다. –

답변

2

. 로

*it->join(); 

가 구문 분석 : 도전으로 복용

*(it->join()); 
+0

[이 링크] (http://en.cppreference.com/w/cpp/language/operator_precedence)를 찾으십시오. – JohnJohn

1

, 난 그냥 C++ (11) 처음에 내 발을 발랐어요. 난 당신이 std::thread 객체의 동적 할당하지 않고 동일한을 달성 할 수 있다는 것을 발견했다 : std::thread이를 rvalue 참조를 복용 생성자와 대입 연산자를 가지고 있기 때문에

#include <iostream> 
#include <thread> 
#include <vector> 

void function() 
{ 
    std::cout << "thread function\n"; 
} 

int main() 
{ 
    std::vector<std::thread> ths; 
    ths.push_back(std::move(std::thread(&function))); 
    ths.push_back(std::move(std::thread(&function))); 
    ths.push_back(std::move(std::thread(&function))); 

    while (!ths.empty()) { 
     std::thread th = std::move(ths.back()); 
     ths.pop_back(); 
     th.join(); 
    } 
} 

이것은 이동하게 작동합니다. 또한 모든 컨테이너는 이동 가능한 객체를 저장하기위한 지원을 얻었으며 재 할당시 복사하는 대신 이동합니다. 이 새로운 C++ 11 기능에 대한 온라인 기사를 읽으십시오. 여기에 설명하기에는 너무 광범위하며 잘 모릅니다.

스레드에 메모리 비용이 발생한다는 우려 사항에 대해 사용자의 접근 방식이 최적화라고 생각하지 않습니다. 오히려 동적 할당 그 자체는 메모리와 성능 모두에서 오버 헤드를 가지고 있습니다. 작은 객체의 경우, 하나 또는 두 개의 포인터와 아마도 약간의 패딩의 메모리 오버 헤드가 엄청납니다. std::thread 개체에 단일 포인터 크기 만있는 경우 놀라지 않을 것이며 이로 인해 100 % 이상의 오버 헤드가 발생합니다.

std::thread 개체에만 해당됩니다. 실제 스레드, 특히 스택에 필요한 메모리는 다른 문제입니다. 그러나 std::thread 개체와 실제 스레드는 1 : 1 관계가 없으며 std::thread 개체의 동적 할당은 그 중 아무 것도 변경하지 않습니다.

재 할당이 너무 비싸기를 두려워하는 경우 재 할당을 피하기 위해 적절한 크기를 미리 확보 할 수 있습니다. 그러나 이것이 정말로 문제가된다면, 쓰래드를 너무 많이 만들고 종료하는 것이고, 작은 객체를 몇 개 옮기는 오버 헤드를 줄여 줄 것입니다. 스레드 풀 사용을 고려하십시오.