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
[59957] Re:Re:Re:친절한 답변 감사드리고요.. 또 생기는 궁금증이..
둘리.CSIEDA [dooly386] 1279 읽음    2010-01-25 14:29
좀 이해가 편하시라고 그렇게 적었고요..
아무래도 정확하게 적어야 되서 수정했습니다.

OnExecute 자체가 Thread에서 호출합니다. Indy socket 하나당 thread가 독립적으로 생성 됩니다.

일반적으로 스레드는 독립적이기 때문에 그 자체를 sync 해줄 필요가 없습니다.

단 여러 스레드가 동시에 같은 리소스(메모리 포함)를 접근할 가능성이 있는 부분에 싱크를 걸어 주는 것 입니다.

잠시 혼란을 드렸다면 죄송합니다.

모든 컴포넌트가 독자적으로 모든 과정을 sync 또는 critical section에 집어 넣지 않습니다.

ADO 자체가 DBMS 와 통신하는 부분은 말씀데로 blocking 하여 sync 가 될 수 있습니다. 그러나
ADO 자체는 그렇지 않다는 것이죠.

지금 indy thread가 ado 를 접근하는 것이지 ado 자체의 통신만을 접근하는것은 아니니까요..





용맨소녀 님이 쓰신 글 :
: 제가 하는 순서가 이렇습니다.
:
: 1. 최초 고정화된 사이즈의 헤더를 받고요.. (안에 명령을 구분하는 변수라든가 패킷 사이즈라든가 그런게 있습니다.)
: 2. 헤더에서 정의된 만큼의 패킷을 받습니다.
: 3. 해당 패킷을 실행합니다.. (유저 생성, DB처리 등이 있겠죠..)
:
: 처음 접속하면 3번 부분에서 유저 정보를 받아서 서버내에 유저구조체에 값을 기록합니다.
: struct
: {
:     char UserID[20];
:     int Score;
:     .....
: } SPlayer;
:
: SPlayer stPlayer[MAX_PLAYER];
:
: 이런 식의 유저 정보가 있지요..
:
: 제가 애매한게 이런 공용의 유저 정보 갱신을 할때 어디서 동기화를 해줘야 하느냐하는 부분인데요..
:
: 그런데, 둘리님께서 써주신 글을 보면 Read가 끝나면 쓰레드에서 탈출하니까 쓰레드 상태가 아니라는 말이 되는데요.. 그러니, 유저 정보 갱신을 위해 동기화가 따로 필요없다는 말이 되지 않나요?
:
: 인디에서 쓰레드가 쓰이는 부분이 Read,Write같은 부분에 한정된다는 말씀인지요..
: 제가 생각해왔던 개념은 OnExecute자체가 인디 내부 쓰레드에 포함되어 있는 함수이기 때문에 DB에다 Synchronize를 걸기도 하고, 패킷에 동기화도 걸고 그런 것이라 생각을 했었거든요..
:
: 그러니, Read류 에만 쓰레드가 적용되는거라면 굳이 패킷도 그렇고, DB에다 Synchronize나 그런걸 걸 필요가 있나하는 부분입니다..
:
: ADO 같은 경우도 명령을 걸어놓으면 백그라운드로 실행되는게 아니고, 처리가 완전 종료될때까지 블럭되는걸로 알고 있거든요..
:
: 그리고, 1소켓을 써서 공용 데이타를 갱신하는거랑 3소켓을 써서 갱신하는거랑 처리방식에 어떤 차이가 발생하는 지도 애매합니다.
:
: 결국 한 마디로 요약한다면 인디의 쓰레드 처리가 어디부터 어디까지를 커버하고 있는지가 애매하다는 거네요..
:
:
: 으흑.. 제가 잘못 알고 있는 부분에 대해서 조언을 해주세요..ㅠㅠ
:
: 둘리.CSIEDA 님이 쓰신 글 :
: : Socket 에서 데이터를 읽어오는 부분이 어디 있나요?
: : 설마 ProcessPacket() 에서 하시는것은 아니겠죠?
: : 짐작컨데 ProcessPacket() 에서 하는듯 하군요. ServerExecute 에 Socket에서 데이터를 읽는 부분이 없으니까요.
: :
: : CriticalSection 이나 Synchronize 에 대하여 정확히 아셔야 합니다. 또한 Indy의 Thread 가 어떻게 도는지 아셔야 합니다.
: :
: : 일단 Server (Client도 마찬가지 입니다만) ServerExecute 에 인디 프로세스가 옵니다. 물론 AThread 를 인수로하여
: : 이 안에 socket 정보를 가지고 옵니다.
: :
: : ServerExecute 에 와서
: :
: : Socket 에서 데이터를 읽으러 들어가야죠.. AThread->Connection->Socket->Read 정도 되는 함수들일 것 입니다.
: : 이렇게 읽으러 들어가면 프로세스가 그 안에서 멈추어 있습니다.
: : 흔히 client socket은 마냥 기다리지 않고 timeout 을 설정하여 해당 timeout 이 지나면 해당 동작을 무시하고 read 에서 나옵니다. 그러나 server socket은 데이터가 올때까지 기다립니다.
: :
: : 기다리다가 원하는 데이터가 오면 해당 함수를 탈출하여 나옵니다. 즉 다음 라인으로 진행하죠.
: : 또한 비정상적인 client 연결 종료도 있을수 있는데,, 이경우도 thread를 빠져 나옵니다. 그러나 에러가 걸려 나오기 때문에 try ... catch... 로 묶어 주셔서 정상적으로 나온건지(원하는 데이터가 옴) , 아니면 기타 다른요인으로 에러가 난것인지를 판단해야 합니다.
: :
: : 아래의 소스에서 보면 무조건 critical section으로 들어갑니다.
: : 그러면 다음 소켓은 해당 critical section으로 들어갈 수가 없습니다.
: :
: : 즉 소켓 하나만 돌겠죠.. 나며지는 기다리고 ,, 데이터 수신도 못하고요..
: :
: : 앞선 socket이 데이터를 받아서 나온후 critical section을 빠져 나와야 다음 소켓이 들어가겠죠.
: :
: : critical section이든 synchronize 든 오랜시간을 머무르시면 않됩니다.
: : 아래의 경우 먼저 들어간 socket이 데이터를 마냥 기다리고 있으면 다른 소켓들은 그냥 앞선 socket 끝나기만
: : 기다려야 겠죠.
: :
: : 데이터가 가끔 오면, 그리고 각 socket들이 서로 다르게 오면 프로세스가 돌 수도 있습니다만.
: :
: : 아마 연결하는 client쪽에서 time out 아 자주 발생할 수 있을 듯 합니다.
: :
: : Thread , CriticalSection, Synchronize 등등 좀 어려운 분야의 코딩입니다. 그러므로 좀더 정확한 코딩이 있어야만
: : 문제가 없을듯 합니다.
: :
: : 소켓에서 데이터 읽은후  DB QUEUE 에 넣는 부분만 critical section으로 묶으세요..
: :
: :
: : 수고하세요...
: :
: : 용맨소녀 님이 쓰신 글 :
: : : 예전에 Indy9의 OnExecute에서 ADO쓸때 동기화에 관한 질문을 했었습니다. ADO호출시 Synchronize를 해야한다는 것이었는데요.. (전 OnExecute이벤트가 하나씩 순차 호출되는걸로 잘못 알고..ㅡ.ㅡ)
: : :
: : : 그럼... 패킷쪽도 같은 식으로 처리해야 하는거란 뜻인데요.. 그런거라면 Synchronize같은거 안쓰고 아예 패킷처리부를 크리티컬 섹션으로 덮어야하는게 깔끔하지 않나 생각됩니다. DB는 큐를 쓰면 될거고요..
: : :
: : : 예를 들어서.. 이렇게 한다면 대충 무난할까요? 지금 만드는건 패킷이 띄엄띄엄오는 거라 성능은 신경안쓰고 만들고 있지만.....
: : :
: : : 암튼, 아래 방식으로 한다면 크레이지아케이드류같은 게임에서 1000명은 커버할려나요? ^^
: : :
: : : 경험많으신 고수님들 답변 부탁드립니다..
: : :
: : : void __fastcall TWin_Main::ServerExecute(TIdPeerThread *AThread)
: : : {
: : :     EnterCriticalSection(&Cs);
: : :     ProcessPacket(AThread); // 이 안에서 DB 관련은 큐로 처리..
: : :     LeaveCriticalSection(&Cs);
: : : }

+ -

관련 글 리스트
59952 Indy9에서 OnExecute 이벤트 내부의 동기화(?) 용맨소녀 1114 2010/01/25
59958     Re:Indy9에서 OnExecute 이벤트 내부의 동기화(?) 둘리.CSIEDA 1580 2010/01/25
59965         Re:Re:감사합니다.. 용맨소녀 892 2010/01/25
59953     Re:Indy9에서 OnExecute 이벤트 내부의 동기화(?) 둘리.CSIEDA 1582 2010/01/25
59956         Re:Re:친절한 답변 감사드리고요.. 또 생기는 궁금증이.. 용맨소녀 1267 2010/01/25
59957             Re:Re:Re:친절한 답변 감사드리고요.. 또 생기는 궁금증이.. 둘리.CSIEDA 1279 2010/01/25
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.