|
멀티쓰레드로 프로그램을 만들다 보면 어떤 쓰레드가 돌고 있는지
관리가 안되기 때문에 디버깅할때 어려움이 있습니다.
항상 모든 쓰레드가 떠 있는 상태라면 그나마 다행이지만
불특정 쓰레드가 돌다가 자동 소멸되고 다른 쓰레드도 마찬가지로 언제 생성되고 소멸되는지
관리가 안된다면 디버깅으로는 최악의 상태죠
이런 멀티쓰레드 애플리케이션 디버깅를 위해서는 몇가지 방법이 있는데요
---------------1. 프로그래밍을 엄청 잘한다.
정말 정말 뛰어난 개발자라면 문제가 생기지 않게 코딩를 하겠죠. 아래 다른분의 답변처럼
Sleep(1) 조차 안들어간 루프가 있다는 얘기인데요. 자기의 코딩에서 그런 루틴을 찾아야합니다.
자기가 만든 코드라면 자신이 코드를 지배해야 하니까 아무런 도구 없이도 찾을 수 있어야 합니다.
---------------2. 로그 기능을 만든다.
멀티쓰레딩 뿐만 아니라 모든 디버깅의 기본인데요
프로그램에 디버깅을 위해 로그파일을 기록 하는 기능을 만듭니다.
다만 만들때 주의할 점은 멀티쓰레드 상황에서도 로그 기록이 제대로되도록
이벤트나 크리티컬섹션을 이용해서 잘 막아주셔야 겠고요
모든 쓰레드 시작점에서 로그찍고,쓰레드 소멸시 로그를 찍어주면
쓰레드의 생성과 소멸을 확인할 수 있습니다.
---------------3. 자신만의 쓰레드 관리자를 만든다.
로그기능과 함께 제가 쓰는 방법인데요. ^^
빌더의 TThrad 클래스도 훌륭하지만 직접 제어 하기는 자기가 만든게 최고지요
자신이 직접 API를 이용해서 쓰레드 클래스를 설계하고
쓰레드의 리스트를 관리할수 있는 구조를 만들어 놓습니다.
그리고 디버깅용 다이얼로그 하나 만들어서 현재 돌고 있는 쓰레드 리스트를 보면서
디버깅 하는것이죠
현재 돌고 있는 쓰레드를 볼 수 있다는것만으로도 디버깅할때 상당히 도움이 됩니다.
또한 쓰레드를 죽이거나 하는 원하는 기능을 추가하기도 쉽고요
전 TThreadList를 이용해서 돌고 있는 쓰레드의 포인터를 관리합니다.
---------------4. 빌더의 쓰레드 디버깅 기능을 이용합니다.
빌더 디버깅 다이얼로그중에 현재 돌고 있는 쓰레드를 보여주는 기능이 있습니다.
그걸 활용하시면되는데 보시면 알겠지만
쓰레드 ID만 표시될겁니다. 어떤 쓰레드가 어떤놈인지 확인이 힘듭니다.
그래서 "Borland C++Builder DG-kor.pdf" 문서에 보시면..
쓰레드 디버깅할때 사용자가 지정한 이름에 나오도록 설정할 수 있는 방법이 있습니다.
아래에 붙여놓을테니까 참고하세요
빌더6.0부터 지원하는듯합니다.
<< 개발자 안내서 일부 발췌 >>
-----------------------------------------------------------------------------
11-12
멀티 스레드 애플리케이션 디버깅
멀티 스레드 애플리케이션을 디버깅할 경우 동시에 실행되는 모든 스레드의 상태를 추적하기
가 어려우며 심지어는 브레이크포인트에서 중지할 때 어떤 스레드가 실행 중인지 확인하는
것조차 어려울 수 있습니다. Thread Status 박스를 사용하여 애플리케이션의 모든 스레드를
추적하고 처리할 수 있습니다. Thread Status 박스를 표시하려면 메인 메뉴에서 View|Debug
Windows|Threads를 선택합니다.
브레이크포인트, 예외, 일시 중단 등의 디버그 이벤트가 발생하면 스레드 상태 뷰에서 각 스레
드의 상태를 나타냅니다. Thread Status 박스를 마우스 오른쪽 버튼으로 클릭하여 해당 소스
위치를 찾는 명령에 액세스하거나 다른 스레드를 현재 스레드로 사용합니다. 스레드가 현재 사
용 중인 것으로 표시되면 해당 스레드에 따라 다음 단계나 실행 작업이 결정됩니다.
Thread Status 박스는 스레드 ID로 애플리케이션의 모든 실행 스레드를 나열합니다. 스레드 객
체를 사용할 경우 스레드 ID는 ThreadID 속성 값입니다. 스레드 객체를 사용하지 않을 경우 각
스레드의 스레드 ID는 BeginThread 또는 BeginThread에 대한 호출에 의해 반환됩니다.
Thread Status 박스에 대한 자세한 내용은 온라인 도움말을 참조하십시오.
스레드 이름 지정
Thread Status 박스에서는 스레드 ID가 어떤 스레드를 나타내는지 알기 어렵기 때문에 개발자
가 스레드 클래스의 이름을 지정할 수 있습니다. Thread Object 다이얼로그 박스에서 스레드
클래스를 만드는 경우 클래스 이름을 입력한 다음 Named Thread 체크 박스를 선택하고 스레
드 이름을 입력한 다음 OK를 클릭합니다.
스레드 클래스의 이름을 지정하면 스레드 클래스에 SetName이라고 하는 메소드가 추가됩니
다. 스레드가 실행되면 SetName 메소드를 제일 먼저 호출합니다.
CLX VCL 애플리케이션에서만 스레드의 이름을 지정할 수 있습니다.
이름 없는 스레드를 이름이 지정된 스레드로 변환
이름 없는 스레드를 이름이 지정된 스레드로 변환할 수 있습니다. 예를 들어 C++Builder 5 또
는 이전 버전을 사용하여 만든 스레드 클래스는 다음과 같은 방법으로 이름이 지정된 스레드
로 변환할 수 있습니다.
1 SetName 메소드를 스레드 클래스에 추가합니다.
//-----------------------------------------------------------------------
----
void TMyThread::SetName()
{
THREADNAME_INFO info;
멀티 스레드 애플리케이션 디버깅
info.dwType = 0x1000;
info.szName = "MyThreadName";
info.dwThreadID = -1;
info.dwFlags = 0;
__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/
sizeof(DWORD),(DWORD*)&info );
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{ }
}
//-----------------------------------------------------------------------
참고 info.szName을 스레드 클래스의 이름으로 설정합니다.
디버거는 예외를 발견하고 개발자가 전달한 구조에서 스레드 이름을 알아냅니다. 디버깅 동
안 디버거는 Thread Status 박스의 스레드 ID 필드에 스레드 이름을 표시합니다.
2 스레드의 Execute 메소드 시작 시 새로운 SetName 메소드를 호출에 추가합니다.
//-----------------------------------------------------------------------
void __fastcall TMyThread::Execute()
{
SetName();
//---- Place existing Execute method code here ----
}
//-----------------------------------------------------------------------
비슷한 스레드에 각각의 이름 할당
같은 스레드 클래스로부터의 모든 스레드 인스턴스는 같은 이름을 갖고 있습니다. 하지만 런타
임 시 다음과 같은 방법으로 각 스레드 인스턴스에 대해 다른 이름을 할당할 수 있습니다.
1 클래스 정의에 다음을 추가하여 ThreadName 속성을 스레드 클래스에 추가합니다.
__property AnsiString ThreadName = {read=FName, write=FName};
2 SetName 메소드에서 아래의 코드를 찾습니다.
info.szName = “MyThreadName”;
위 코드를 다음과 같이 변경합니다.
info.szName = ThreadName;
3 다음과 같은 방법으로 스레드 객체를 만듭니다.
1 일시 중지된 상태에서 만듭니다. 11-11페이지의 "스레드 객체 실행"을 참조하십시오.
2 MyThread.ThreadName=”SearchForFiles”;와 같이 이름을 할당합니다.
3 스레드를 다시 시작합니다. 11-11페이지의 "스레드 시작 및 중지"를 참조하십시오.
-----------------------------------------------------------------------------
이범상 님이 쓰신 글 :
: 좀 덩어리가 큰 프로그램을 만들었는데
: 요놈을 구동시키면 CPU점유율이 80~90%입니다.
:
: 분명 어떤 쓰레드 한놈이 CPU를 잡고 있는거 같은데
: 쓰레드를 여기저기 사용하다보니 어떤놈인지 구분이 안됩니다.
: 디버깅도 힘들고...
:
: 이럴때 어떤놈이 CPU를 잡고 있는지 알수 있는 방법 없습니까???
:
: 고수님들 갈켜주세요 ^^
|