2009-08-07 6 views
22

상당히 간단한 스레드 응용 프로그램을 작성하려고하지만 boost 스레드 라이브러리를 처음 사용합니다. 내가 일하고 있어요 간단한 테스트 프로그램은 다음과 같습니다(simple) boost thread_group 질문

#include <iostream> 
#include <boost/thread.hpp> 

int result = 0; 
boost::mutex result_mutex; 

boost::thread_group g; 

void threaded_function(int i) 
{ 
    for(; i < 100000; ++i) {} 

    { 
     boost::mutex::scoped_lock lock(result_mutex); 
     result += i; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    using namespace std; 

    // launch three threads 
    boost::thread t1(threaded_function, 10); 
    boost::thread t2(threaded_function, 10); 
    boost::thread t3(threaded_function, 10); 

    g.add_thread(&t1); 
    g.add_thread(&t2); 
    g.add_thread(&t3); 

    // wait for them 
    g.join_all(); 

    cout << result << endl; 

    return 0; 
} 

그러나, 나는 컴파일하고 내가 분명히

$ ./test 
300000 
test: pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed. 
Aborted 

의 출력을 얻을이 프로그램을 실행하면, 결과는 정확하지만 난 걱정 본질적으로 동일한 구조를 가진 실제 프로그램이 join_all() 지점에서 멈추고 있기 때문에 특히이 오류 메시지에 대해 누군가 나에게 무슨 일이 일어 났는지 설명 할 수 있습니까? 이를 수행하는 더 좋은 방법이 있습니까? 즉, 많은 수의 스레드를 실행하고 외부 컨테이너에 저장 한 다음 프로그램을 계속하기 전에 모든 스레드가 완료 될 때까지 기다릴 수 있습니까?

도움 주셔서 감사합니다.

답변

25

나는 프로그램이 종료 할 때 호출되는 thread_group 소멸자로 인해 문제가 발생했다고 생각합니다. 쓰레드 그룹은 쓰레드 객체의 파괴를 책임지고 싶어한다. boost::thread_group 설명서를 참조하십시오.

스택의 스레드 개체를 주 기능의 범위에서 로컬 변수로 만듭니다. 따라서 프로그램이 종료되고 thread_group이 프로그램을 삭제하려고 시도 할 때 이미 파괴되었습니다.솔루션으로

, 새로운와 힙에 스레드 객체를 생성하고 자신의 파괴를 돌봐 thread_group 보자

boost::thread *t1 = new boost::thread(threaded_function, 10); 
... 
g.add_thread(t1); 
... 
+0

"새"메모리 할당 사이의 줄임표를 제거하고 thread_group에 전달해야합니다. 그렇지 않으면 개입 코드에서 문제가 발생하여 (즉, throw) 스레드가 누출됩니다. –

+0

예, 이것이 사실 인 것으로 보이며 큰 프로그램에서도 버그의 원인이었습니다. 이제 작업 예제에서 다음을 사용합니다. // 세 개의 스레드 시작 g.add_thread (new boost :: thread (threaded_function, 10)); g.add_thread (새 부스트 :: thread (threaded_function, 10)); g.add_thread (새 부스트 :: thread (threaded_function, 10)); – RandomGuy

+1

좋은 방법은 std :: unique_ptr 또는 유사한 해결책을 사용하고 ptr.get()을 사용하여 group_thread에 스레드를 제공하는 것입니다. – Klaim

2

add_thread()는 전달한 스레드의 소유권을 가져옵니다. 스레드 그룹은 스레드를 삭제합니다. 이 예제에서는 스택에 할당 된 메모리를 삭제합니다.

멤버 함수 add_thread()

공극 add_thread (스레드의 THRD *);

전제 조건 :

표현이 THRD 삭제가 잘 형성 하고 정의되지 않은 동작이 발생하지 않습니다.

효과 : 부스트의

소유권 가져 :: 스레드 객체가 THRD가 가리키는 및 그룹에 그것을 를 추가 할 수 있습니다.

사후 조건 :

this-> 크기()가 1 씩 증가.

코드에 문제가 있는지, 아니면 예제 버그인지 잘 모릅니다. 그렇지 않으면 코드가 정상적으로 보입니다.

24

당신이 당신의 스레드에 대한 핸들을 필요로하지 않는 경우, 사용해보십시오 모든 스레드를 관리 할 필요가 완화 thread_group :: create_thread() :

// Snip: Same as previous examples 

int main(int argc, char* argv[]) 
{ 
    using namespace std; 

    // launch three threads 
    for (int i = 0; i < 3; ++i) 
     g.create_thread(boost::bind(threaded_function, 10)); 

    // wait for them 
    g.join_all(); 

    cout << result << endl; 

    return 0; 
} 
+0

create_thread는 여전히 스레드에 대한 핸들을 반환합니다. http://www.boost.org/doc/libs/1_39_0/doc/html/thread/thread_management.html#thread.thread_management.threadgroup.create_thread. 이 경우 create_thread를 사용할 수있는 이유는 add_thread와 달리 스레드 그룹이 스레드를 삭제할 책임이 없기 때문입니다. – shank22

0

그것은 위의 어느 것도 실제로 질문에 대답하지 보인다.

나는 비슷한 문제를 만났다. 이 경고의 결과 (. : 87 : __pthread_mutex_lock : pthread_mutex_lock.c 어설`뮤텍스 -> _ 데이터 _owner == 0은 '실패 중단됨.)를 가끔 프로그램이 스레드를 누설하고 boost_resource_error 예외를 일으킬 것입니다.

대부분의 스레드가 아직 실행 중이지만 종료되지는 않았지만 join_all() 후에 프로그램이 계속 실행되는 것처럼 보입니다.