C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[73319] Re:Re:Re:Re: 프로세스와 쓰레드 관계
빌더(TWx) [builder] 4363 읽음    2016-01-30 02:25
답변:



프로그램에서 별도의 쓰레드를 생성하지 않는 프로그램이라고 할지라도...
멀티 쓰레드를 지원하는 OS에서는 커널 로더가 기본적인 쓰레드인 'main thread'는 항상 생성하게 됩니다.
모든 프로세스는 적어도 하나 이상의 쓰레드는 갖고 있는 셈이죠.

'main thread'에서 입력을 받고, 'Worker Thread'를 생성해서 백그라운드로 MP3 파일을 디코딩해서 음악을 플레이하는
어떤 프로그램이 있다고 가정해 봅시다.

플레이를 Pause 버튼을 눌러서 'Worker Thread'가 Suspend 상태가 되었다고 해서... 프로그램 자체도
Suspend 상태가 되는 것은 아니지요. 단지 워커 쓰레드만 서스펜드 상태가 되었을 뿐, 메인 쓰레드는 키보드 입력을 받고 있으니.
프로그램 자체는 Suspend 상태가 아닙니다.


NtResumeProcess()를 이용하는 한...

NtQuerySystemInformation()로 받은 쓰레드 리스트를 갖고...
순회하면서 쓰레드 개별적으로 Suspend 샹태를 일일히 체크할 필요가 전혀 없습니다.

어떤 프로세스의 쓰레드들을 Resume 해주는 건 NtResumeProcess() 내부에서 알아서 처리해주니까...
쓰레드 리스트의 가장 첫번째 요소인 'main thread'의 Suspend 상태만 체크하면 됩니다. (ThreadList[0])

다만 이때 주의 할 것은...

메모리를 할당해서 NtQuerySystemInformation()를 호출해서 얻은 데이타는 NtResumeProcess()를 호출하기 전에
얻은 복사본이란 것을 주의 해야 합니다.

따라서, 프로세스가 Suspend된 상태에서 NtResumeProcess()를 호출하면 커널 내부 자료구조가 변경되므로...
변경이 반영된 쓰레드 상태를 체크하기 위해선 NtQuerySystemInformation()을 다시 호출해서... 변경된 쓰레드 상태 값을
다시 복사해 와서 체크하는 구조로 로직을 작성해야 합니다. (ThreadList[0], 메인 쓰레드만 Suspend 상태 체크)

덧붙여서...

인터넷 익스플로어의 경우...

IE 웹브라우저를 열면 iexplore.exe 라는 프로세스 이름을 갖는 프로세스들이 몇개 생생될 수도 있는데...
이런 경우는 생성된 프로세스들을 같이 일괄적으로 Resume하거나 Suspend 해야... 웹브라우저 프로그램이 전체적으로
Resume/Suspend 되는 결과를 얻을 수 있습니다.




님이 쓰신 글 :
: waitreason 값을 5와 대조해서
:
: 5면 계속 Resume 을 주도록 만들었는데
:
: 간혹 쓰레드 중에 waitreason 값이 기본이 5인것인지 어쩐것인진 몰라도
:
: 리줌을 천번 줘도 계속 5의 값을 유지하고 있는 녀석이 있네요
:
: 실제로 프로그램은 Resume 되서 잘 움직이고 있구요
:
: 해당 부분 코드는 아래와 같습니다.
:
:
:
: for(int i = 0; i < infoP->ThreadCount ; i++)
: {
:     while (infoP->Threads[i].WaitReason == 5)
:     {
:         DV(("[IDFS] %s Resume",StrProcess));
:         NtResumeProcess(ProcessHandle);
:         if (pBuffer) HeapFree(GetProcessHeap(), NULL, pBuffer);
:         goto Re;
:     }
: }
: 얼덜 님이 쓰신 글 :
: : 감사합니다!! 덕분에 좋은걸 많이 알아가네요
: :
: :
: : 빌더(TWx) 님이 쓰신 글 :
: : : 얼덜 님이 쓰신 글 :
: : : : 안녕하세요 프로세스를 서스펜드 하다가
: : : :
: : : : 의문점이 생겨서 질문드립니다.
: : : :
: : : : 예전에는 프로세스랑 쓰레드 둘다 스냅샷을 찍어서 pid 동일한거 찾은다음
: : : :
: : : : 쓰레드를 SuspendThread 시켰는데 이 방식이 불안정(?) 하다는 말을 들어서
: : : :
: : : : NtSuspendProcess 함수를 써서 서스펜드 시키게 됬습니다
: : : :
: : : : 문제는 기존 함수였던 SuspendThread / ResumeThread 함수들은 리턴값으로 서스펜드 카운트를 반환해서
: : : :
: : : : 몇번 서스펜드 명령이 있었는지를 보고 그만큼 Resume 을줬었는데
: : : :
: : : : NtSuspendProcess 함수는 그런걸 반환안하더라구요 그냥 반환값 무조건 0;
: : : :
: : : : 그래서인지 서스펜드를 여러번 시켜서 서스펜드 카운트는 쌓였는데 Resume 은 한번만 줘서
: : : :
: : : : 프로그램이 정상작동을 하지 않는등의 문제가 생깁니다.
: : : :
: : : : NtSuspendProcess 함수로 서스펜드 카운트를 받는 방법이 있을까요?
: : : :
: : : : 그리고 NtSuspendProcess 랑 SuspendThread 랑 무슨 차이가 있나요?
: : : :
: : :
: : :
: : : 답변:
: : :
: : :
: : :
: : : NtSuspendProcess()는 리턴값으로 NT_STATUS 를 사용하므로... 성공하면 0 값을 리턴하게 됩니다.
: : : 커널 내부 자료구조에서 카운트를 유지하고 있어서 NtSuspendProcess()를 여러번 호출했다면 프로세스를 Resume 시키기
: : : 위해선 NtSuspendProcess()를 호출한 횟수 만큼 NtResumeProcess()를 호출해줘야 합니다.
: : :
: : : 그에 반해서...
: : : NtResumeProcess()는 여러번 호출해도 상관 없습니다. NtSuspendProcess()를 호출한 수 만큼 NtResumeProcess()를
: : : 호출하면 프로세스가 Resume 상태가 되고, 그 후에 또 다시 NtResumeProcess()를 호출해도 카운트 되는 것은 없다는 거죠.
: : :
: : : 카운트 값은 커널 내부 자료구조에서 갖고 있으므로...
: : : 위 두개의 API를 이용해서 처리할 경우.. 타겟 프로세스 상태가 Suspend상태인지 아닌지를 알아내서 Suspend 가 풀릴 때 까지
: : : NtResumeProcess()를 계속 호출하는 구조로 로직을 구성해야 합니다.
: : :
: : : 타겟 프로세스의 Resume/Suspended 상태는 NtQuerySystemInformation()를 이용해서 알아 낼 수 있습니다.
: : : 어떤 프로세스의 SYSTEM_THREAD 라는 자료구조의 WaitReason 필드 값이 '5'이면 Suspended 상태 입니다.
: : :
: : :
: : : SuspendThread()를 이용하는 것 보다 NtSuspendProcess()을 이용하는 게 유리한 것은...
: : :
: : : 하나의 프로세스는 여러개의 쓰레드를 가질 수 있고, 각기의 쓰레드를 개별적으로 Resume/Suspended 처리를 하게 되면
: : : 쓰레드 간의 종속관계로 인해서 문제가 발생할 수도 있기 때문 입니다. 잘못하면 데드락 상황이 발생할 수도 있고요.
: : :
: : :
: : : NtQuerySystemInformation(), NtSuspendProcess(), NtResumeProcess() 등의 함수는 Undocumented API 이지만...
: : : XP 이후부터 현재의 Windows 10 에 이르기 까지 계속 사용되고 있습니다. 커널 변경에 따라서 함수의 내부 Implementation이
: : : 바뀔 수는 있어도... Win32 레이어가 존재하는 한... 이 API들이 사라질 가능성은 ... 전혀 없다고 봐도 무방 하지요.
: : :
: : : 시스템 유틸리티 프로그램을 만들 때... 상당히 자주 사용되는 API이기도 합니다.(MS에서도 자신들이 만든 프로그램에서 자주
: : : 사용하기도 합니다.) Undocumented API라고 해서 꺼릴 필요는 없다는 겁니다.
: : :
: : :
: : :
: : :

+ -

관련 글 리스트
73310 NtProcessSuspend 함수 질문 얼덜 4315 2016/01/27
73311     Re:NtProcessSuspend 함수 질문 빌더(TWx) 4479 2016/01/27
73315         Re:Re:NtProcessSuspend 함수 질문 얼덜 4477 2016/01/28
73317             Re:Re:Re:NtProcessSuspend 함수 질문 4154 2016/01/28
73319                 Re:Re:Re:Re: 프로세스와 쓰레드 관계 빌더(TWx) 4363 2016/01/30
73324                     Re:Re:Re:Re:Re: 프로세스와 쓰레드 관계 얼덜 4073 2016/02/01
73326                         Re:Re:Re:Re:Re:Re: 프로세스와 쓰레드 관계 얼덜 4145 2016/02/01
73327                             Re:Re:Re:Re:Re:Re:Re: 프로세스와 쓰레드 관계 얼덜 4168 2016/02/01
73328                                 Re:Re:Re:Re:Re:Re:Re:Re: 데모 프로그램 빌더(TWx) 4282 2016/02/01
73332                                     Re:Re:Re:Re:Re:Re:Re:Re:Re: 데모 프로그램 얼덜 4307 2016/02/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.