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
[27683] Re:ㅋㅋㅋ
최보현.U&I [uriduri] 1136 읽음    2003-10-29 11:26
안녕하세요~ 현지아빠 입니다.

일단 뭐 그럴수가 없다는 겁니다.

카크님 말씀처럼 데이타가 너무 많이 들어 와서 그럴수도 있다 ?
요것도 아닙니다. 뭐 생각 해보면 간단한 문제 입니다.
시리얼 통신 해봐야 최고 속도가 겨유 115200 입니다. 바이트수로 따서 봐야
초당 11520 바이트 = 1.15 k 밖에 되지 않습니다.
이런데 뭐 XT 컴퓨터도 아니고 컴퓨터가 그걸 못 쫒아 가겠습니까
100 M 네트웤 그러니까 초당 10 MByte 통신을 해도 컴퓨터가 버벅 될일이 없는데 말입니다.
그러니 구조적인 문젠 아닐꺼구요~

또 시리얼 컴포넌트 안에 스레드가 이상하다라고 생각 하시겠져~
근데 시리얼 콤포안에 있는 쓰레드가 단순히 자료가 있던 없던 무조건
시리얼 포트로 들어오는 자료가 있는지 계속 데이타를 읽어 보는 구조가 아닙니다.
만약 그렇다면 ...
쓰레드 프로그램을 잘못 하면 ... 컴퓨터가 무지 버벅 데겠지요~
하지만 실제로 시리얼 컴포넌트 안에 있는 쓰레드는 자료가 들어 올경우만
돌아가도록 되어 있습니다.

쓰리드의 소스를 잠시보면

while(pDevice->IsThreadAlive) {
    if(!WaitCommEvent(pDevice->DevHandle, &Event, &pDevice->EvnRead)) {
         switch (Error = GetLastError()) {
              case ERROR_IO_PENDING:    break;
              case 87:                break;
              default:               break;
         }
     }   else    {
         ClearCommError(pDevice->DevHandle, &Error, &CommStatus);
         if(CommStatus.cbInQue == 0 && CommStatus.cbOutQue == 0)  continue;
     }

     if(!pDevice->TryClose)  {
           ThreadEvent = WaitForMultipleObjects(
                             SERIAL_THREAD_EVENT_MAX-1, pDevice->EventArray,
                             FALSE, INFINITE);
     }   else    {
         ThreadEvent = SERIAL_THREAD_EVENT_TERMINATE;
     }
     switch(ThreadEvent)    {
              ...................................
이러식으로 되어 있습니다.
while 루프가 무조건 도는게 아니라.

WaitCommEvent(pDevice->DevHandle, &Event, &pDevice->EvnRead)
ThreadEvent = WaitForMultipleObjects(
                     SERIAL_THREAD_EVENT_MAX-1, pDevice->EventArray,
                     FALSE, INFINITE);

이런식으로 두개의 블럭킹 함수가 while 루프의 무조건적인 실행을 막고 있습니다.
물론 위 두개의 블럭킹 함수가 블럭킹 되었을때는 컴퓨터는 따른일을 합니다.
그리고 위 두개의 블럭킹 함수들이 실제로 통신 포트에서 데이타가 들어 와야지
블럭킹이 플린다 이겁니다. 그것도 단순히 1 Byte 들어 왔다구 풀리는것이 아니라 ...
어느정도 버퍼링이 되거나 또는 시간이 경과 되어야지 블럭킹이 플리지요~~

그러니 기껏 통신 포트 하나로 시스템이 버벅 된다는것은 말이 않됩니다.

어플리케이션이 프로그램을 잘못 했다는 말밖에는 않되겠네요~

그럼 ^^


김성진.kark 님이 쓰신 글 :
: 먼저 답부터 하겠습니다.
:
: 빈폼에 현님의 시리얼통신 콤포 두개다 올려놓고 컴파일해 보시길.
: 씨피유 다 잡아 먹나요? 답은 NO 입니다.
: 그럼 실제로 돌리면 100% 잡아 먹는다? 그건 정재훈 님께서 잘못하신것입니다.
: 쓰레드는 실제로 이렇게 되어있다고 보면 되겠지요.
:
: //예제 2개의 쓰레드
:
: //thread 1 : 루프타임설정 100msec
: while(1)
: {
:   .... //할일1
: }
:
: //thread 2 : 루프타임설정 200msec
: while(1)
: {
:   .... //할일2
: }
:
: thread 1을 봅시다. 작성자가 원하는것은 while 루프를 도는 타임이 100msec가
: 되게 하고 싶습니다. 근데 할일1이 100msec가 넘어가면? 작성자가 잘못한것이죠.
: 타임이 100msec를 넘어도 된다면, 측정후 시간을 늘여야하고, 그렇지 않다면 할일1
: 의 수행시간을 줄여야겠지요. thread 2도 마찬가집니다.
: 그런데 thread 1의 할일1이 50msec 밖에 시간이 안걸려서 50msec가 남았다고 봅시다.
: 그럼 씨피유의 자원은 어떻게 될까요?
: 답은 할일1을 하고 어떻게 하냐에 달려있습니다. 즉 아래와 같이 설정을 한다면,
:
: //thread 1 : 루프타임설정 100msec
: //NOTE: 가상소스입니다.
:
: get_systime(&timer); // 현재 시스템 시간을 timer에 적재
:
: while(1)
: {
:   .... //할일1
:
:   elaps = get_elapstime(&timer);  // 현재 시간인 timer 기준으로 얼마나 지났는지 적재
:   if(elaps < 100)                 // 만일 100 msec 보다 빨르다면
:     delay_thread((100-elaps));    // 100 - elaps 시간만큼 쓰레드를 쉬어라
: }
:
: 씨피유 자원은 당연히 남을 뿐만 아니라, OS 사양만큼 100msec 를 지키겠지요.
:
: 하지만 아래와 같이 했다면,
:
: //thread 1 : 루프타임설정 100msec
: //NOTE: 가상소스입니다.
:
: while(1)
: {
:   .... //할일1
: }
:
: 100msec보다 빨리끝났지만, 쉬지 않고 또다시 루프를 돌기때문에 항상 씨피유를 점유하겠지요.
: 윈도 환경에서는 리얼타임을 잘 적용하지 않기 때문에, 대부분 타협해서 이렇게 코딩하시겠죠.
:
: //thread 1 : 루프타임설정 100msec
: //NOTE: 가상소스입니다.
:
: while(1)
: {
:   .... //할일1
:   sleep(50); // 50msec 만큼 쉬어라.
: }
:
: 할일1이 대충 50msec 걸린다고 했으니,  50msec 만큼 쉬어라 라고 하는 것이죠. 이렇게되면,
: 할일1의 50msec가 정확할 수 없기 때문에 정확하게 100msec를 지키지는 못하지만 비슷하게
: 되면서 씨피유 100% 점유 안하겠죠.
:
: 시리얼로 RX만하는데도 시간이 부족해서 도저히 쉬라고 할 여유분이 없다면? 그건 시리얼로
: 감당안되는 거랍니다. 다른 통신 모듈을 고려 하셔야죠. 아니면 TX 쪽에서 버퍼링해서 틈을
: 주시던지요. 상황에 따라 다릅니다.
:
: 즉 sleep(1) 이라는 코드 하나만 넣어보시길. 씨피유 100% 점유? NO 이니다.
:
:
: 그럼 다른 얘기를 좀 하겠습니다. 제목처럼 정재훈님의 글은 참으로 곤란한 글입니다.
: 최보현님께서 고생해서 만든 콤포를 공개하시고, 강좌도 올렸습니다. 근데, 검증되지않은
: 문제를 가지고 마치 현님 콤포가 문제가 있는 것처럼 오해할 수 있는 글을 올리셨습니다.
: 의도하셨든 안하셨든 오해할 수 있다는 것이 문제입니다. 여기에서 답변 주시고, 자료를
: 공유하시는 분들은 어떤 대가를 바라는 것이 아니지 않습니까? 최소한 그런 분들에 대한
: 예는 지켜야 한다고 생각합니다.
:
: 참고로 저도 동일한 콤포를 사용해서 여러 플젝을 수행했구요, 지금도 잘 사용하고 있는
: 중입니다.
:
: 그럼...
:
:
:
: 정재훈 님이 쓰신 글 :
: : 안녕하세요
: :
: : 최보현님의 시리얼통신 소스를 쓰고있는데
: : 이게 구동만 시키면 통신 쓰레드가 시스템을 100% 잡아먹습니다. 물론 쓰레드니까 다른 프로그램이 돌아가지만 다른 통신모듈은 점유가 거의 2%수준이던데 이건 어떻게 해결하나요?
: : 저도 해결해본답시구 쓰레드를 하나 만들어서 돌려보니 100%로 점유하는군요..
: : 점유를 낮추는 방법은 무엇인가요?
: :
: : 쓰레드 우선순위를 tpIdle 로 해도 점유상태는 변화가 없습니다.
: : 시원한 답변들 부탁드립니다.
: : 미리 감사드립니다. 그런 즐건 프로그램하세요. ^^*

+ -

관련 글 리스트
27678 이건 좀 곤란한 글이군요. 김성진.kark 1006 2003/10/29
27683     Re:ㅋㅋㅋ 최보현.U&I 1136 2003/10/29
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.