2010-11-19 5 views
4

내 응용 프로그램이 CreateThread를 사용하여 만든 트레드 다음의 알고리즘이 실행 종료 할 준비가되면 :적절한 정리는 스레드 닫 실패하는 경우 - C++

_bCloseRequested = TRUE; 
dwMsThen = ::GetTickCount(); 

do 
{ 
    ::GetExitCodeThread(m_hThread, &dwExitCode); 
    dwMsNow = ::GetTickCount(); 
} 
while((dwExitCode == STILL_ACTIVE) && ((dwMsNow - dwMsThen) < 50000UL)); 

스레드가 5 할당 초 이내에 종료 실패 할 경우를, 스레드 핸들을 닫거나 열어 둘 수 있습니까? 감사.

답변

6

먼저 스레드가 이와 같이 완료 될 때까지 기다리지 마십시오. 대기중인 모든 사용 가능한 CPU 시간을 모두 먹을 것입니다. 스레드가 완료되는 데 더 오래 걸리는 단점이 있습니다! 대신이 같은

사용 무언가 :

WaitForSingleObject(m_hThread, 50000); 

말했다 : 당신은 스레드 실행을 떠나고 싶지 여부는 스레드가 무엇을하는지에 따라 달라집니다. 주 앱이 다른 일을하기 시작하더라도 실행할 수 있습니까? 쓰레드를 죽이면 열려있는 중요한 파일 (파일, 연결, 데이터베이스 등)이 열려 있습니까? 스레드를 죽일 지 또는 실행 상태로 둘지 결정하기 전에이 모든 것을 고려해야합니다.

+0

스레드는 직렬 포트에서 비동기 입력을 수신하는 데 사용됩니다. 그러나 스레드는 직렬 포트를 여는 데 사용되는 리소스를 소유하지 않습니다. 스레드가 소유 한 유일한 자원은 수신 된 데이터를 처리하기 위해 관리하는 순환 버퍼입니다. 스레드가 닫히면 버퍼가 더 이상 필요하지 않습니다. –

0

아니요. 스레드가 깔끔하게 종료되지 않도록 수정해야하며 간단하게 스레드에 참여해야합니다. 다른 모든 것은 단지 해킹 일뿐입니다.

+0

스레드가 _bCloseRequested 변수 자체를 검사하지 않는다면 문제의 실제 원인이된다고 말하면서이 부분을 확장합니다. 장기 실행 사용자 시작 작업조차도 해당 사례를 올바르게 처리하기 위해 사용자가 종료를 요청했는지 확인해야합니다. –

+0

@Harper Shelby : 예, 스레드는'_bCloseRequested'를 모니터링하여 안전하게 정리하고 종료 할 수 있습니다. –

+1

개인적으로 나는 bool 또는 다른 변수를 검사하여 종료시기를 결정하는 것이 나쁜 설계라고 생각합니다. 이벤트 구동 시스템에서는 대부분의 스레드가 대기 상태 (조건 변수, 파일 설명자 등)를 기다려야합니다 ... 따라서 종료하려면 이상적으로 깨어나서 종료하도록 명시해야합니다 (대신 그 (것)들에 출구 시간다는 것을 통지하기 위하여 의지하십시오) ... 또한, 시간의 99.999999 %이기 때문에, 프로그램 검사의 기간 내내 가변을 검사하는 것은 비쌀, 나올 시간이 아니다. – dicroce

2

스레드 핸들을 기다리십시오. 시간이 너무 오래 걸리는 경우 앱을 종료하고 종료해야하며 버그로 인해 스레드를 종료하지 못하게해야합니다.

static const DWORD TIMEOUT_VALUE(50000); 

if (WaitforSingleObject(m_hThread, TIMEOUT_VALUE) != WAIT_OBJECT_0)) 
{ 
    // thread did not exit in time, log and exit process 
} 
1

좋은 질문입니다.

여기에는 몇 가지 접근 방법이 있습니다.

첫 번째 방법은 이상적인 접근 방법으로 생각합니다. 그리고 그것은 절대로 스레드를 종료하지 않는 것입니다.

  1. 스레드가 동기화 개체를 소유하는 경우

    , 그들은 공개되지 않습니다
  2. RAII 객체는
  3. 을 정리할 수있는 기회를 얻을하지 않습니다 그 이유는 일부 거물 여러하지만 여기에 있습니다 할당 된 메모리는 당신이 certian 커널 호출의 중간에있는 경우
  4. , 당신은

그래서 스레드가 종료되지 않은 이유, 당신은 이유를 식별하는 것이이 방법으로가는 전체 응용 프로그램 호스 수 해제되지 않습니다 그 문제를 해결하십시오. 문제가 심화 될 수 있습니다. 교착 상태, 경쟁 조건 등을 찾을 수 있습니다. 정적 분석은 이러한 문제를 찾는 데 도움이 될 수 있습니다.

이상적인 접근 방식은 항상 요구해야하는 것입니다. 그리고 이것을 할 때 스핀 락을 사용하지 않는 것이 가장 좋습니다. 대신 스레드 핸들에서 Wait()이 시간 초과됩니다. 방적함으로써 자원을 낭비하고 기다리는 스레드의 시간 조각을 훔칩니다.

그러나 실세계에서는 프로덕션 코드에서 다른 모든 것이 실패 할 경우 대비책이 필요합니다. 먼저 여러 가지 방법을 시도하여 스레드가 스스로 종료되도록해야합니다. 모든 것이 절대적인 최후의 수단으로 실패하면 스레드를 종료하십시오. 그러나 좀비 스레드를 죽이는 위험 때문에 일단이 작업을 완료하면 전체 응용 프로그램을 다시 시작해야합니다. 스레드를 종료하면 프로세스를 비 결정적 상태로 만들 수 있습니다. 그러니 다시 시작하십시오.오류 메시지를 기록하고 응용 프로그램을 종료 한 다음 다시 시작하십시오.

+0

자세한 의견을 보내 주셔서 감사합니다. 그것은 확실히 명심하고있는 일입니다. 필자의 주된 전문 분야는 임베디드 세계에 있기 때문에 나는 웃어야 만합니다. 거기에서, 당신이 그것을 부르는 것처럼 "회전"은 일반적인 관행입니다. 그래도 좋은 지적이 있습니다. 추천하는'WaitForSingleObject'를 구현하려고합니다. 모든 세부 사항에 +1. –

+0

@ 짐 : 필자는 임베디드에 대한 코딩을 한 번도 해본 적이 없지만 회전은 매우 일반적이라는 사실에 놀랐다. 특히 한정된 자원으로 16 기가비트 램을 사용하는 듀얼 CPU 머신보다 비 회전이 더 중요 할 것으로 기대됩니다. : –

+0

정말 시스템 구성 방법에 달려 있습니다. 이벤트 구동 OS를 사용하는 경우 가능한 한 폴링을 피해야합니다. 그러나, 내가 한 일의 대부분은 그렇게 복잡하지 않습니다. 일반적으로 플래그를보고 주 루프를 돌면 설정됩니다. –

관련 문제