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
[27777] Re:[질문]쓰레드..
박지훈.임프 [cbuilder] 1029 읽음    2003-11-05 06:10
이상한 곳이 좀 많군요.

일단, 두 쓰레드에서 자신을 Thread1, Thread2라고 지칭하고 있는데, 클래스 이름과 동일하군요?
컴파일이 된다는 것이 이상한데... 아마도 소스 일부만 발췌하신 것 같은데요.
(이렇게 알아보기도 어렵게 일부를 잘라서 올리시면 질문을 해석하고 답변하기가 정말 괴롭습니다)

또 설사 쓰레드 변수의 이름이 클래스 이름과 다르다고 해도, 쓰레드 클래스의 멤버함수가 자신을 this라고
하거나 생략하지 않고 Thread1->... 이렇게 참조하는 것도 이상하고...

첫번째 쓰레드의 Execute() 함수 내부를 보면 두번째 스레드를 생성해놓고 바로 다음번 루프에서 정지시키는데..
두번째 쓰레드의 FreeOnTerminate가 false로 되어있으니 파괴되지도 않을 거고... 그런데도 NULL을 할당해서
쓰레드 객체를 메모리 어딘가에 잃어버린 후에 다시 생성하고...
FreeOnTerminate가 true로 되어있어도 마찬가지라고 하셨는데, 일단 적어도 쓰레드를 잃어버리지는 않을 거구요.

직접적으로 가장 문제가 되어 보이는 부분은...
간단히 요약하자면, 첫번째 쓰레드의 Execute() 내에서 두번째 쓰레드의 Terminate()를 호출하고는
조금 있다가 첫번째 쓰레드의 Terminate()를 호출했는데...
아마도 님께서는 두번째 쓰레드의 Terminate()를 먼저 호출했으니 당연히 먼저 실행될 거라고 생각하신 듯 한데...

Terminate()를 먼저 호출했다고 해도, 이 함수가 하는 역할은 단지 Terminated 속성을 true로 설정하는 것
뿐입니다. 그리고 이 변수를 체크하여 종료하는 것은 오직 님이 작성하신 Execute() 함수의 책임이구요.
따라서 두번째 쓰레드의 Execute()로 실행이 넘어가기 전에는 두번째 쓰레드는 절대로 파괴되지 않지요.

그런데 문제는, 두번째 쓰레드의 Terminate() 함수를 호출한 곳이 첫번째 쓰레드의 Execute()라는 겁니다.
이런 경우에는 CPU 시간이 각 쓰레드로 배분되는 시간적 간격의 영향을 받겠지만, 아무래도 두번째 쓰레드로
실행이 넘어가기 전에 첫번째 쓰레드의 Terminate() 함수를 비롯하여 루프의 가장 선두인 while(!Terminated...)
이 라인까지도 실행될 가능성이 높습니다. 이 라인까지 실행되어버리면 첫번째 쓰레드는 즉시 끝나버리죠.

물론 첫 쓰레드의 Execute() 루프 내에서 호출한 UpdateThread() 함수가 상당히 시간을 많이 잡아먹어서
이 함수의 실행 중에 반드시 두번째 쓰레드로 실행이 넘어간다면 다행이지만, 그렇지 않다면 두번째 쓰레드로
실행이 넘어가기 전에(일단 실행이 넘어가야 종료여부를 체크하고 종료하겠죠?) 첫 쓰레드가 먼저 끝나버리게
되어버리죠.

그리고, Win32 Error 중에 1400 에러는 Invalid window handle입니다.

그럼...








초보 님이 쓰신 글 :
: 전 쓰레드 안에 쓰레드가 또 존재합니다.
: 우선 외부에서 쓰레드를 호출하고요..
:
: //외부에서 호출
:     if(!Thread1) Thread1= new Thread1(ThreadSel);
:     else {
:       BootThread->Terminate();
:       BootThread = NULL;
:     }
:
: //
:
: //쓰레드1 생성자
: __fastcall Thread1::Thread1(int Num)
:         : TThread(true)
: {
:   FreeOnTerminate = false;   //false로 설정
:   ThreadNum = Num;
:   Resume();
:   Priority = tpTimeCritical;
: }
: void __fastcall Thread1::Execute()
: {
:   while(!Terminated && ThreadFlag == 1 )
:   {
:         if(!Thread2)  Thread2= new Thread2(true);  //새로운 쓰레드 생성
:         else {
:           Thread2->Terminate(); 
:           Thread2= NULL;        
:         }
:         UpdateThread();  //쓰레드에서 함수 실행.
:         ThreadFlag = 0;
:         Thread1->Terminate();   //Thread1제거
:         Thread1= NULL;
:     }
: }
: ////////////두번째 쓰레드
: //쓰레드2 생성자
: __fastcall Thread2::Thread2(bool OnOff)
:         : TThread(true)
: {
:   FreeOnTerminate = false;   //위 함수에서 두번쨰 쓰레드를 없애기 위헤 Terminate를
:                              // 썼으므로false로 설정 . 그러나 만일 자동으로 할려구 해도 위에
:                              //Terminate를 없래고 true로 해도 에러가 발생합니다.
:   TurnOnOff = OnOff;
:   Resume();
:   Priority = tpNormal;
: }
: void __fastcall Thread2::Execute(void)
: {
:     while(!Terminated && TurnOnOff == true)
:     {
:       UpdateTurnOn();
:       TurnOnOff = false;
:     }
:     EndBulOnOff();
:     Thread2->Terminate();  //이부분에서 제거합니다.
:     Thread2= NULL;       //
: }
:
: 컴파일을 해서 디버깅을 해도 Thread1이 Thread2보다 먼저 소멸되서 생기는 문제 같은데..
: 명확히 잘 모르겠네여..
: 위의 쓰레드가 진행되는 동안 중간에 프로그램을 닫으면
: "Win32Error ..code 1400"가 발생하는데 잘 모르겠습니다.
: 잘못된 코드가 있으면 좀 알려주세여..
:

+ -

관련 글 리스트
27770 [질문]쓰레드.. 초보 830 2003/11/04
27777     Re:[질문]쓰레드.. 박지훈.임프 1029 2003/11/05
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.