CloseHandle (), TerminateThread (), ExitThread () 의 차이
6339 단어 Windows
스 레 드 의 handle 은 스 레 드 자 체 를 가리 키 는 것 이 아니 라 '스 레 드 의 커 널 대상' 을 가리 키 는 것 입 니 다. 모든 커 널 대상 은 커 널 에서 분 배 된 메모리 블록 일 뿐 커 널 에서 만 접근 할 수 있 습 니 다.이 메모리 블록 은 데이터 구조 로 구성원 이 유지 대상 의 각종 정보 (eg: 안전성 설명, 참조 계수 등) 를 책임 집 니 다.
CloseHandle()
Create Thread 가 성공 한 후에 hThread 의 handle 을 되 돌려 주 고 커 널 대상 의 계수 에 1 을 더 하면 Close Handle 을 참조 하여 1 을 줄 이 고 0 이 되면 시스템 은 커 널 대상 을 삭제 합 니 다.
그러나 이 handle 은 이 스 레 드 를 완전히 대표 할 수 없습니다. 이것 은 스 레 드 의 '표지' 일 뿐 시스템 과 사용 자 는 이 를 이용 하여 해당 하 는 스 레 드 를 필요 로 하 는 조작 을 할 수 있 습 니 다.스 레 드 가 성공 적 으로 생 성 된 후에 이 핸들 을 사용 하지 않 아 도 됩 니 다. 생 성 성공 후 스 레 드 가 종료 되 기 전에 바로 CloseHandle 을 떨 어 뜨 릴 수 있 지만 스 레 드 의 운행 에 영향 을 주지 않 습 니 다.
CloseHandle () 을 실행 하지 않 은 결과:
스 레 드 가 실 행 된 후에 CloseHandle () 을 통 해 인용 수 를 1 로 줄 이지 않 으 면 프로 세 스 가 실 행 될 때 커 널 대상 의 유출 이 발생 하고 문형 유출 과 같 지만 메모리 유출 과 달리 시스템 효율 에 어느 정도 부정적인 영향 을 미 칠 수 있다.그러나 프로 세 스 가 끝 난 후에 도 시스템 은 자동 으로 이 자원 들 을 정리 해 줄 것 이라는 것 을 기억 하 세 요.그러나 여기 서 이런 방법 을 추천 하지 않 는 것 은 좋 은 프로 그래 밍 습관 이 아니 기 때문이다!(프로그램 이 실 행 될 때 커 널 대상 이 유출 될 수 있 습 니 다. 그러나 프로 세 스 가 실 행 될 때 시스템 은 모든 내용 을 정확하게 제거 할 수 있 습 니 다. 또한 이 상황 은 모든 대상, 자원, 메모리 블록 에 사 용 됩 니 다. 즉, 프로 세 스 가 종 료 될 때 시스템 은 어떠한 대상 도 남기 지 않 습 니 다.)
TerminateThread()
함수 의 설명 은 다음 과 같 습 니 다.
BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode);
역할:
온라인 스 레 드 밖에서 스 레 드 를 종료 하고 스 레 드 를 강제 종료 하 는 데 사용 합 니 다.
매개 변수 설명:
HANDLE htread: 종 료 된 스 레 드 의 핸들 은 CWinThread 지침 입 니 다.
DWORD dwExitCode: 종료 코드.
반환 값:
함수 실행 에 성공 하면 0 이 아 닌 값 을 되 돌려 주 고 실행 에 실패 하면 0 을 되 돌려 줍 니 다.getlasterror 를 호출 하여 되 돌아 오 는 값 을 얻 습 니 다.
Terminate Thread 를 하지 말 라 는 말 을 수 없 이 들 었 습 니 다. 업무 중 에 자주 사용 되 는 것 일 뿐 문제 가 없 는 것 같 습 니 다.오늘 고강도 테스트 에서 용서 할 수 없 는 잘못 이 발견 되 었 다.아래 의 예 를 참조 하 시 오
DWORD __stdcall mythread(void*)
{
while( true )
{
char* p = new char[1024];
delete [] p;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h = CreateThread(NULL, 0, mythread, NULL, 0, NULL);
Sleep(1000);
TerminateThread(h , 0);
h = NULL;
char* p = new char[1024]; // ,
delete [] p;
return 0;
}
왜 자물쇠 가 잠 겨 있 지?new 연산 자 는 작은 블록 더 미 를 사용 합 니 다. 전체 프로 세 스 가 메모 리 를 할당 하고 회수 할 때 같은 자 물 쇠 를 사용 해 야 합 니 다.이 자 물 쇠 를 점용 할 때 스 레 드 가 죽 으 면 (즉, 죽 기 전에 이 스 레 드 가 new 또는 delete 작업 중) 다른 스 레 드 는 new 또는 delete 를 사용 할 수 없습니다. hang 으로 표 시 됩 니 다.
Terminate Thread 를 사용 하지 말 라 고 분명히 일 깨 워 주 었 지만 그 이 유 는 피 가 뚝뚝 떨 어 지 는 것 이 아니 었 다.오늘 발 견 된 이 bug 는 이 책의 가 치 를 입증 했다.
다른 주의: 많은 임시 네트워크 작업 은 항상 Terminate Thread 를 사용 합 니 다. 네트워크 가 통 하지 않 을 때의 종료 체제 로 서 나중에 고 쳐 야 합 니 다.예 를 들 어 이 스 레 드 를 자 생 자멸 시 키 고 스스로 물 러 나 게 하 는 것 이다.
ExitThread 는 스 레 드 를 끝 내 는 방법 을 추천 합 니 다. 이 함 수 를 호출 할 때 현재 스 레 드 의 스 택 이 풀 리 고 스 레 드 가 종 료 됩 니 다. TerminateThread 함수 에 비해 이 스 레 드 에 추 가 된 DLL 제거 작업 을 잘 수행 할 수 있 습 니 다.
스 레 드 종료 두 함수: ExitThread () 와 TerminateThread () 스 레 드 실행 을 종료 하려 면 다음 네 가지 방법 을 사용 할 수 있 습 니 다. 스 레 드 함수 가 순환 을 종료 하고 돌아 올 수 있 습 니 다. (최선 의 방법 )。ExitThread 호출 을 통 해 함수, 스 레 드 는 스스로 취소 합 니 다. )。같은 프로 세 스 나 다른 프로 세 스 의 스 레 드 를 TerminateThread 로 호출 합 니 다. 함수 )。이 스 레 드 의 주 프로 세 스 가 실행 을 중지 합 니 다 (사용 하지 마 십시오) )。스 레 드 운행 을 중지 하 는 방법 을 소개 하고 스 레 드 가 운행 을 중지 할 때 어떤 상황 이 발생 하 는 지 설명 한다.
1. 스 레 드 함수 반환 은 항상 스 레 드 를 이러한 형식 으로 설계 해 야 합 니 다. 즉, 스 레 드 가 종 료 될 때 되 돌아 갈 수 있 습 니 다. 이것 은 모든 스 레 드 자원 이 정확하게 제거 되 는 것 을 확보 하 는 유일한 방법 입 니 다. 스 레 드 가 되 돌아 올 수 있다 면 다음 사항 의 실현 을 확보 할 수 있 습 니 다. a) 스 레 드 함수 에서 만 든 모든 C + 대상 은 취소 함 수 를 통 해 정확 한 취소 함 수 를 사용 할 것 입 니 다.실행 취소. b) 운영 체 제 는 스 레 드 스 택 에서 사용 하 는 메모 리 를 정확하게 방출 합 니 다. c) 시스템 은 스 레 드 의 종료 코드 (스 레 드 의 커 널 대상 에서 유지) 를 스 레 드 함수 의 반환 값 으로 설정 합 니 다. d) 시스템 은 스 레 드 커 널 대상 의 사용 수 를 점차 줄 일 것 입 니 다.
2. ExitThread 함 수 는 라인 에서 ExitThread 함 수 를 호출 하여 라인 의 운행 을 강제 할 수 있 습 니 다. 이 함 수 는 라인 의 운행 을 중지 하고 운영 체제 에서 이 라인 에 사용 되 는 모든 운영 체제 자원 을 삭제 합 니 다. 단, C + + 자원 (예: C + + 클래스 대상)취소 되 지 않 습 니 다. 이 때문에 ExitThread 를 호출 하 는 대신 스 레 드 함수 에서 돌아 오 는 것 이 좋 습 니 다. 물론 ExitThread 를 사용 할 수 있 습 니 다. dwExitThread 매개 변 수 는 시스템 에 스 레 드 의 종료 코드 설정 을 알려 줍 니 다. ExitThread 함 수 는 실행 이 종료 되 었 기 때문에 더 많은 코드 를 실행 할 수 없습니다. 스 레 드 실행 을 종료 하 는 가장 좋 은 방법 은 스 레 드 함 수 를 되 돌려 주 는 것 입 니 다. 단, 이 절 에서 소개 한 방법 을 사용 하면 ExitThread 함수 가 Windows 에서 실행 을 취소 하 는 것 임 을 알 아야 합 니 다.스 레 드 의 함수 입 니 다. C / C + 코드 를 작성 한다 면 ExitThread 를 사용 해 서 는 안 됩 니 다. Visual C + + 런 타임 라 이브 러 리 함수 endthreadex 를 사용 해 야 합 니 다. Microsoft Visual C + + 컴 파 일 러 를 사용 하지 않 는 다 면 컴 파 일 러 공급 업 체 는 ExitThread 의 대체 함 수 를 가지 고 있 습 니 다. 이 대체 함수 가 무엇 인지 상관 하지 않 고 사용 해 야 합 니 다. 이 장 뒤 에는 endthreadex 의 작업 을 설명 합 니 다.그것 과 의 중요성.
3. TerminateThread 함수 가 TerminateThread 함 수 를 호출 해도 스 레 드 의 운행 을 중지 할 수 있 습 니 다: ExitThread 와 다르다 항상 호출 된 스 레 드 를 취소 합 니 다. TerminateThread 는 모든 스 레 드 를 취소 할 수 있 습 니 다. hThread 인 자 는 실행 중 지 된 스 레 드 를 표시 하 는 핸들 에 사 용 됩 니 다. 스 레 드 가 실 행 될 때 종료 코드 는 dwExitThread 가 됩 니 다. 매개 변수 가 전달 하 는 값 입 니 다. 또한 스 레 드 의 커 널 대상 의 사용 계수 도 점차 줄 어 들 었 습 니 다. TerminateThread 함 수 는 비동기 로 실행 되 는 함수 입 니 다. 즉, 스 레 드 가 종료 되 었 다 는 것 을 알려 줍 니 다. 그러나 함수 가 되 돌 아 왔 을 때 스 레 드 가 취소 되 었 다 는 것 을 보증 할 수 없습니다. 이 스 레 드 가 종료 되 었 다 는 것 을 정확히 알 고 싶다 면 WaitForSingleObject 나 WaitForSingleObject 를 호출 해 야 합 니비슷 한 함수 입 니 다. 스 레 드 를 전달 하 는 핸들 입 니 다. 잘 설 계 된 프로그램 은 이 함 수 를 사용 하지 않 습 니 다. 실행 이 중 지 된 스 레 드 가 취소 되 었 다 는 알림 을 받 을 수 없 기 때 문 입 니 다. 스 레 드 가 올 바 르 게 제거 되 지 않 고 취소 되 는 것 을 방지 할 수 없습니다. ExitThread 를 되 돌리 거나 호출 할 때 주의 하 십시오. 스 레 드 를 취소 하 는 방법 은 이 스 레 드 의 메모리 스 택 도 취소 되 었 습 니 다. 단, Terminate Thread 를 사용 하면 ,그러면 스 레 드 가 있 는 프로 세 스 가 실행 을 중지 하기 전에 시스템 은 이 스 레 드 의 스 택 을 취소 하지 않 습 니 다. Microsoft 는 일부러 이러한 방법 으로 Terminate Thread 를 실현 합 니 다. 。실행 중인 다른 스 레 드 가 강제 삭 제 된 스 레 드 스 택 의 값 을 참조 하려 면 다른 스 레 드 에 접근 하 는 데 문제 가 발생 합 니 다. 삭 제 된 스 레 드 스 택 을 메모리 에 남 겨 두 면 다른 스 레 드 가 계속 잘 실 행 됩 니 다. 이 외 에 스 레 드 가 종 료 될 때 DLL 은 보통 알림 을 받 습 니 다. Terminate Thread 를 사용 하여 강제 적 으로 실행 할 경우스 레 드 가 종료 되면 DLL 은 알림 을 받 지 않 습 니 다. 이 는 적절 한 삭 제 를 막 을 수 있 습 니 다 (자세 한 정 보 는 20 장 참조).
4. 프로 세 스 가 종 료 될 때 스 레 드 ExitProcess 와 TerminateProcess 함 수 를 취소 하면 스 레 드 의 실행 을 중지 할 수 있 습 니 다. 이 스 레 드 는 종 료 된 프로 세 스 의 모든 스 레 드 를 종료 합 니 다. 또한 전체 프로 세 스 가 종료 되 었 기 때문에 모든 스 레 드 의 스 택 을 포함 합 니 다.함 수 는 모든 남 은 스 레 드 에서 TerminateThread 를 호출 하 는 것 처럼 프로 세 스 의 남 은 스 레 드 를 강제로 취소 합 니 다. 마찬가지 입 니 다. 이것 은 정확 한 프로그램 제거 가 발생 하지 않 았 음 을 의미 합 니 다. 즉, C + 대상 취소 함수 가 호출 되 지 않 았 고 데이터 가 디스크 로 옮 겨 지지 않 았 음 을 의미 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[WinIoT/라즈파이] VS2019로 만든 UWP의 sln을 라즈파이 3+WinIoTCore로 원격 디버깅을 할 수 없을 때의 대처2021년 1월 시점에서 라즈파이 3에 WindowsIoTCore를 넣고 VisualStudio2019에서 UWP 앱을 새로 만들고 디버깅하려고 했는데 잘 디버깅할 수 없었다. 구체적으로는, 「리모트 디버거에 접속할...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.