|
근데 한가지 아직도 이해가 안가는게...
try __finally 를 사용해서 (중간에 exception 이 발생해도) Unlock()을 수행했을텐데요..
왜 두번째 수행할 땐 Lock() 에서 멈추어 있을까요??
Unlock() 이 두번 실행되어서 그런가요? 흠..
혹시나하고 아래와 같이 __finally{ } 이후에 나오는 Unlock() 을 없앴더니
잘 수행되네요.. ^^
감사합니다!!!!!!!
__finally
{
thdlist->UnlockList();
}
// thdlist->UnlockList();
황경록 님이 쓰신 글 :
: 질문1) 에 대한 답변입니다.
:
: Lock() 함수는 Unlock() 함수와 페어(pair) 입니다.
:
: try __finally 를 사용하는 이유는 Lock() 이후 처리를 수행한 후 Unlock() 을 수행하지 못하는 경우
: 리스트가 lock 걸린 상태로 남아 있기 때문에 문제가 발생합니다.
:
: 따라서 try __finally 를 사용해서 코드 중간에 exception 이 발생했을 경우에서 __finally 블럭의 unlock() 을
: 시켜 주기 위한 것입니다.
:
: 질문2) 는 CommandHandler 를 사용하지 않는 경우 클라이언트에서 전송되어진 리딩에 대한 이벤트는
: OnExecute 로 집중되는 것입니다. 따라서 OnExecute 에 처리를 해주시면 되겠습니다.
: 흐~ 근데 사실 이부분은 저도 안해본거라 ^^.... 근데 맞을 겁니다! -_-;;
:
:
: ★래미★ 님이 쓰신 글 :
: : 질문1)
: :
: : 아래와 같이 TThreadList를 써서 각 클라이언트에 데이터를 보내려고 합니다.
: : 별 문제 없이 보였는데..
: : 황경록님 말씀 중에.. try{ }__finally{ }
: : 요 부분을 참고해서 이걸 넣어야되나.. 하고 테스트 해봤더니..(아래서 블러킹된거 지우고요..)
: : 처음 한번은 되구요.. 그담엔..
: : TList* list = thdlist->LockList(); 요 부분에서 블럭되네요..
: : 왜 그런지 궁금해요~~
: : 근데.. 해놓고보니 요건 클라이언트를 하나씩 호출하는 것이라 동기화가 필요없을 거 같기두 해요
: : 아직도 넘 막막하기만 하네요.. ㅠㅠ
: :
: : //---------------------------------------------------------------------------
: :
: : void __fastcall TForm1::SendToClient()
: : {
: : //send data
: : char sBuf[BUF_SIZE];
: : sprintf(sBuf, "Server -> Client Test Message!");
: :
: : TThreadList* thdlist = TCPServer->Threads;
: : TList* list = thdlist->LockList();
: : if(list->List==NULL) return;
: : TIdPeerThread* thd;
: : TIdTCPServerConnection* con;
: :
: : // try
: : // {
: : for(int i = 0; i < list->Count; i++){
: : thd = (TIdPeerThread*)list->Items[i];
: : con = thd->Connection;
: : con->WriteBuffer(sBuf, BUF_SIZE); //write
: :
: : RichEdit1->SelAttributes->Color = clGreen;
: : RichEdit1->Lines->Add (GStack->LocalAddresses->Strings[0]); //local IP
: : }
: : // }
: : // __finally
: : // {
: : // thdlist->UnlockList();
: : // }
: : thdlist->UnlockList();
: : }
: :
: : //---------------------------------------------------------------------------
: :
: : 질문2)
: :
: : TCPServer 의 OnExecute() 함수에서는 여러개의 클라이언트가 접속해도
: : 여기서 다 처리가 가능한가요??
: : 아니면 여기서도 TThreadList 이런걸 써야되는지..
: : 제 생각에는 필요없을거 같은데요.. 넘 막연해서 답답해요....
: : 하나에서 열까지 다 모르는지라.. 질문이 넘 초보적이네요 ㅠㅠ
: :
: : 그럼.. 좋은 저녁시간 되세요~~
: :
: : //---------------------------------------------------------------------------
: :
: : void __fastcall TForm1::TCPServerExecute(TIdPeerThread *AThread)
: : {
: : if( AThread->Stopped || AThread->Terminated ) return;
: : TIdTCPServerConnection *con = AThread->Connection;
: : char Message[BUF_SIZE]={0,};
: : int iExpectedLen=0, iStackBufSize=0;
: :
: : try
: : {
: : Application->ProcessMessages();
: : do
: : {
: : iExpectedLen = con->ReadFromStack( true, 1000, false );
: : iStackBufSize = con->InputBuffer->Size;
: :
: : if(AThread->Terminated)
: : {
: : throw Exception( "Termination Detected!" );
: : }
: :
: : } while( iStackBufSize < iExpectedLen ); // expected packet size
: :
: : if(iExpectedLen > 0){
: : con->ReadBuffer(Message, iExpectedLen);
: : MessageHandler(Message, AThread);
: : }
: : }
: :
: : catch(const Exception &e)
: : {
: : RichEdit1->Lines->Add( "Termination Detected!" );
: : con->Disconnect();
: : }
: : }
: : //---------------------------------------------------------------------------
: :
: :
: :
: : 황경록 님이 쓰신 글 :
: : : TThreadList 는 말 그대로 쓰레드에서 동기화가 필요 없이(?) 사용하도록 만들어진 클래스입니다.
: : :
: : : 제가 팁앤트릭에 올린 TZSynchronize 가 바로 TThreadList 사용하는 매커니즘(???)입니다.
: : :
: : : Add(), Remove() 등의 함수를 동기화 코드 없이 사용할 수 있구요.
: : :
: : : 그러나 결국 ^^:: 이녀석도 그냥 TList 입니다 ^^ TList 에 TZSynchronize 를 넣어둔것(?)과 같은것이죠.
: : :
: : : 그래서 사용할 때
: : :
: : : TThreadList* pTList;
: : :
: : : ...
: : :
: : : TList* pList = pTList->LockList()
: : :
: : : try
: : : {
: : : pList->Items....
: : : }
: : : __finally
: : : {
: : : pTList->Unlock();
: : : }
: : :
: : : 뭐 이런식으로 되는것입니다. ^^
: : :
: : : ★래미★ 님이 쓰신 글 :
: : : : TThreadList* thdlist = TCPServer->Threads;
: : : : ~~~
: : : :
: : : : 여기서 동기화가 자동으로 이루어지는지..?
: : : :
: : : : Synchronize를 따로 시켜야되는지..? 궁금합니다
: : : :
: : : : 쓰레드 넘 어려운거 같아요 ㅠㅠ
|