2014-10-13 1 views
5

말, 멤버 변수로 스레드 포인터를 포함하는 C++ 클래스가 있습니다. 스레드는 프로그램이 종료 될 때까지 계속 실행됩니다. 소멸자에서 포인터를 삭제하면 해당 시점에 스레드가 아직 완료되지 않은 것 같습니다.이 방법이나 트릭을 관리하는 가장 좋은 방법은 무엇입니까?소멸자에서 안전하게 스레드 포인터를 삭제하는 방법은 무엇입니까?

샘플 코드 :

class Car { 
public: 
    Car(); 
    ~Car(); 
private: 
    boost::thread *m_runningThreadPtr; 
}; 


Car::Car() { 
    m_runningThreadPtr = new boost::thread(); 
} 

Car::~Car() { 
    delete m_runningThreadPtr; // The thread should be still running now. 
            // Problematic if it was deleted here? 
} 
+1

boost :: shared_ptr 처리를 시도하십시오. http://stackoverflow.com/questions/13823300/pointer-to-boostthread http://www.boost.org/doc/libs/1_55_0/doc/html/ thread/thread_management.html – fox

+2

왜 처음에는 쓰레드에'new'를 쓰고 있습니까? 꽤 불필요한 것 같습니다. – juanchopanza

+0

당신은 정상적으로 그 쓰레드를 끝내고 다음과 같이 끝내기 위해 합류해야합니다 : Car :: ~ Car() {m_runningThreadPtr-> join(); 삭제 m_runningThreadPtr; } – wshcdr

답변

1

기본적으로 소멸자이 안전 여부, 여전히 실행중인 경우 스레드를 죽일 terminate()를 호출 스레드가 시간에 무엇을하고 있는지에 따라 달라집니다. 스레드가 완료 될 때까지 기다리고 싶다면 join()으로 전화를 걸고 스레드에게 종료를 알리는 일종의 동기화 시스템 (심지어 전역 플래그도 포함)을 사용할 수 있습니다.

+0

이것은'std :: thread'가 아니라'boost :: thread'입니다. 'detach'를 호출하고'terminate'를 호출하지 않을 것입니다. 그럼에도 불구하고 분리 된 쓰레드가 죽지 않으므로 쓰레드 객체를 삭제하는 것이 "무해하다"(여전히 바람직하지는 않지만). – Damon

0

삭제하지 마십시오. 완료되면 스레드를 삭제하십시오.

+1

API에 따라 위험 할 수 있습니다. 예 : 쓰레드 객체의 소멸자가'join()'을 호출하여 효과적으로 교착 상태를 일으킬 수있다. –

0

실행할 코드가 더 이상 없을 때 프로그램이 완료됩니다. 스레드가 여전히 코드를 실행하고 있습니까? 그런데 왜 당신의 프로그램은 끝났다고 생각합니까?

그래서 스레드가 실제로 완료되었다고 가정하는 것이 합리적입니다. 즉, 스레드에서 .join()으로 전화를 걸면 delete에 전화해도됩니다.

1

당신이 찾고있는 행동의 종류에 따라 다릅니다.

개체를 삭제하고 소유 된 스레드를 중지 한 다음 해당 스레드 개체를 삭제하려는 경우 스레드가 수시로 확인하는 중지 플래그가 있어야합니다. 소멸자에서 stop 플래그를 설정 한 다음 스레드에서 join()을 호출합니다. 포인터가 반환되면 포인터를 안전하게 삭제할 수 있습니다.

개체를 삭제하고 스레드가 완료 될 때까지 스레드를 계속 실행하려면 스레드 기능의 끝과 같이 더 똑똑한 메커니즘이 필요합니다. 스레드가 귀하의 스레드에서 join()을 호출하는 콜백을 호출 한 다음 delete입니다. 물론, 당신은 스레드 객체에 대한 포인터를 스레드 함수에 가지고 있어야합니다. 작업이 완료되면 안전하게 삭제할 수 있습니다 두 번째 옵션에 대한 있도록 boost::thread의 경우

편집 , 그것은 단순히 소멸자에서 분리합니다. 그러나이 경우에는 std::thread의 소멸자와 함께 작동하지 않으므로 프로그램을 종료하게됩니다. 하지만 detach()을 직접 호출 한 다음 delete을 수동으로 호출 할 수도 있습니다. 따라서 실제로 사용중인 API를 살펴 봐야합니다.

관련 문제