제가 사실은 큐를 만들어서 사용해야 하는데....큐의 개념은 알고 있는데 구현할 시간이 없어서 어찌어찌 하다가 STL 예제를
보고 이렇게 쓰고 있습니다. 이렇게 사용해도 아무런 문제가 없는지 모르겠습니다. 어느분은 환형큐를 만들어서 메모리를 밀 설정해두고
사용하라구 하던데 콘트롤하기가 어려워서 큐에서 자료가 나가는시점은 쓰레드가 큐에 자료가 있으면 가저 갑니다. 메모리 문제나
그런부분에 대해서 잘몰라서 고수님은조언 부탁한다. 참고 : 통신모듈에서 사용예정 입니다.
//----------- *.h
부분 입니다. #ifndef MainH #define MainH
#include <queue.h>
. . .
struct TCommand { AnsiString
IPADDR; byte
BYAPSS; byte
COMMAND; byte
CRC; };
class
TFrm_Main : public TForm { __published: //
IDE-managed Components TServerSocket *Srv_Socket;
. . .
public: // User declarations
TCommand Com_List;
//
Command struct queue <TCommand> Com_Queue;
// Queue . .
// ----------------unit 부분 입니다.
void
__fastcall TFrm_Main::CreatCommand(AnsiString IP, byte bypass, byte command,
byte crc) { Com_List.IPADDR = IP;
Com_List.BYAPSS = bypass; Com_List.COMMAND = command;
Com_List.CRC = crc; Com_Queue.push(Com_List);
//큐에 입력 }
//---------------------------------------------------------------------------
void __fastcall TFrm_Main::But_OnClick(TObject *Sender) {
Com_Queue.pop(); //큐에서 1건 삭제 }
//---------------------------------------------------------------------------
저도 리눅스에서 서버를 만들면서 STL 을 사용했는데.
쓰레드에서 문제입니다. 바로 동기화 때문이죠. STL 의 쓰레드
안전성은 개발자가 책임져야
한다고 합니다. 저도 리시큐에 데이타가 오는 것을 쓰레드가 검사하여 있으면 데이타를 파싱
하는 것으로했는데.. 리눅스에서는 뮤텍스를 윈도우즈에서는 크리티컬섹션으로 이용해서
동기화를 맞추어 주었습니다.
아직까지는 잘 돌아가고 있습니다만은 ^^;; 매번 큐를 검사해야 하는 쓰레드 땜시 생기는 서버 부하
를 줄이기
위해서 리눅스에서 Real Time Signal 서버로 변환할려고 노력중이지만 실력이 딸리다 보
니 -_-;; (잘 아시는 분
없나요??)
아무튼 쓰레드끼리 한데이타에 대해서 동기화를 하는데
CCriticalSection cs;
cs.Lock(); if(...) { ... } else {
cs.Unlock(); ... }
이런 식으로 사용하시지
마시구요. Lock() 안 풀릴 수도 있습니다. 영원히 블럭되는거죠 -_-;;
class CSectionObject {
public: void Lock() { cs.Lock(); } void
UnLock() { cs.Unlock(); } private: CCriticalSection cs;
};
class CSyncronized { public:
CSyncronized(CSectionObject *pSO) {
m_pSO = pSO;
m_pSO->Lock(); }
~CSyncronized() {
m_pSO->Unlock(); } private:
CSectionObject *m_pSO; };
를 만들어서 동기화 할 것이 있다고한다면 CSectionObject
에서 상속 받은 후
CQueue : CSectionObject { public:
queue<int> myQ; };
소스 코드에서 CQueue
mainQ;
{ //Sync block CSyncronized sync(&mainQ);
mainQ.myQ.push(10); //작업 }
식으로 하세요
위처럼하면
블럭을 들어옴과 동시에 Lock() 이 걸리고 블럭을 나감과 동시에 Lock() 풀립니다.
안전하죠. 도움이 되길
바랍니다 ;)
Ansi C++ STL은 원래 스레드에 대한 고려가 전혀 없습니다. 김성철님 답글대로 개발자가 직접 스레드 동기화를
제어하는 코드를 작성해야 합니다. 참고로 SGI STL implementation
(http://www.sgi.com/tech/stl/download.html)을 설치하시면 읽기에 대해서만 스레드 안전(thread
safety)한 컨테이너를 쓰실 수 있습니다.
만약 STL에서 제공하는 기능(알고리듬 등)이 필요없으시고 단지
큐라는 자료구조만 필요하시다면, 차라리 VCL의 TThreadList를 사용해보세요.
다음은 빌더 헬프에 있는 예제입니다.
TThreadList::LockList()를 호출하면 스레드 안전한 TList를 쓸 수 있습니다.
TList
*pList = MyThreadList->LockList();
try { for (int
X = 0; X < pList->Count; X++)
Something(pList->Items[X]); } __finally {
MyThreadList->UnlockList(); }
|