2013-10-02 3 views
4

문제가되는 코드가 다음과 같이 줄어 들었습니다. 나 자신의 스레드에서 멤버 함수를 실행하는 클래스 C 있습니다. C의 소멸자에서이 스레드를 완전히 종료하고 싶습니다. 이것은 c가 main (1) 내에 정의되어있는 한 정상적으로 작동하지만 글로벌 변수 (2)가 아닌 경우에는 작동합니다. 후자의 경우 스레드 함수가 반환되지만 t.join()이 중단된다는 것을 알 수 있습니다.전역 변수의 소멸자에서 호출 될 때 thread.join이 실패하는 이유

#include <mutex> 
#include <condition_variable> 
#include <thread> 
#include <iostream> 

using namespace std; 

class C 
{ 
public: 
    C() 
    { 
     stop = false; 
     t = thread(&C::ThreadFunc, this); 
    } 
    ~C() 
    { 
     stop = true; 
     cv.notify_all(); 
     if (t.joinable()) 
     { 
      cout << "joining" << endl; 
      t.join(); 
      cout << "joined" << endl; 
     } 
    } 

private: 
    void ThreadFunc() 
    { 
     while (true) 
     { 
      unique_lock<mutex> lock(m); 
      cv.wait(lock, [&]{return stop;}); 
      cout << "returning" << endl; 
      return; 
     } 
    } 

    thread t; 
    mutex m; 
    condition_variable cv; 
    bool stop; 
}; 

C c; // does *not* work (2) 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    C c; // does work (1) 
    return 0; 
} 

글로벌 변수를 사용하는 이유는 이것이 실제로 dll의 일부라는 것입니다. DLL_PROCESS_DETACH의 DllMain에서 소멸자가 트리거되면 같은 문제가 발생합니다. 이 문제에 대한 설명 및 해결책이 있습니까?

+2

'C :: stop'은'atomic '이어야합니다. 설정하기 전에 소멸자에서 뮤텍스를 잠글 필요가 있습니다. 그렇지 않으면 데이터 경합이 생깁니다. –

+0

@Jonathan : 나는 그것을 시도했지만 그것이 문제의 원인이 아닙니다. – Emile

답변

4

교착 상태입니다. t이 종료 될 때까지 기다리는 동안 종료하려면 t에 필요한 잠금 장치를 잡고 있습니다.

t의 분리 프로세스의 일부로 말하면, DLL에 대한 호출이 이루어집니다. 부분적으로 연결된 스레드 (join을 호출 한 스레드)가있을 때 DLL이 현명하게 요청을 처리 할 수 ​​있습니까? 일단 분리가 시작되고 분리가 완료 될 때까지 DLL은 일관성없는 상태이며 스레드 연결 및 분리 작업을 감지 할 수 없습니다.

프로세스가 제어 할 수없는 컨텍스트에있는 동안 실제로 스레드에 참가하려고하지 않으려합니다.

+0

그건 의미가 있습니다. 그런데 어떻게 종료를 처리 할 수 ​​있습니까? 종료시 t에 가입하지 않으면 응용 프로그램이 중단됩니다. (실행 중에 문서가 파괴되면 std :: terminate가 호출되기 때문에 생각합니다.) – Emile

+0

@Emile 상황에 따라 다르지만 아마도 분리해야합니까? (스레드가 종료 될 때 수행해야 할 작업에 따라 다름) –

+0

위의 예제 코드에서는 분리 할 수 ​​있지만 실제 프로그램에서는 분리 할 수 ​​없습니다. R6010 - abort()가 mutex.c에서 호출되었습니다. (38) : 사용 중 mutex가 삭제되었습니다. 정리가 다른 방법이 필요하지만이 문제는이 DLL이 실제로 루아 인터프리터의 C 확장 모듈이므로 어쩌면 나는 Lua 스크립트에서^Z를 누를 때 정리할 방법이 있는지 Lua 커뮤니티에 물어볼 수있다. 감사합니다 . – Emile

관련 문제