효율적인 동기화를 위한 아이디어 하나

2007.09.29 02:32

단장 조회 수:3306 추천:49


programming/server 2006/12/09 17:27  

서버 프로그래밍시에 동기화 처리 시 여러 가지 골치아픈 것들이 있는데, 나름대로 머리 써서 사용했던 팁 하나 소개합니다.

리스트 컨테이너 사용시, 읽는 중에 쓰게 되면 문제가 생기게 됩니다. 그래서

EnterCriticalSection(&m_CS);
읽기작업();
LeaveCriticalSection(&m_CS);

EnterCriticalSection(&m_CS);
쓰기작업();
LeaveCriticalSection(&m_CS);


이런 식으로 크리티컬섹션 같은 동기화 객체를 이용해서 동시에 접근하지 못하도록 처리합니다. 하지만 여기서 약간의 문제라고 하면 동시에 읽는 것도 안 된다는 것입니다. (참고로 stl 컨테니어들도 동시에 여러 개의 쓰레드에서 읽는 것은 가능합니다.)

서버 프로그래밍 시 모두 문제가 되는 것은 아니지만 주로 방 리스트 처리 같은 경우에는 불필요한 블럭이 생길 수 있습니다. 많은 클라이언트에서 읽기를 요청하고, 많은 쓰레드에서 읽기를 시도하지만, 하나의 쓰레드만 리스트에 접근할 수 있기 때문이죠. 그렇다고 쓰기의 빈도도 높냐고 하면 그렇지도 않은 게, 읽기에 비하면 현저하게 적기 때문입니다. (방리스트, 유저리스트, 등등등)

여기서 어떻게 하면 읽기는 동시에 접근하되, 쓰는 동안은 읽기의 접근을 막을 수 있느냐고 고민을 하게 되었습니다. 그래서 아주 완전한 형태는 아니지만, 거의 원하는 형태의 답을 얻었는데, 아래와 같습니다. (pseudo 코드니 의미만...)

int idx = m_CS_cnt++%_MAX_CS_CNT;
EnterCriticalSection(&m_CS[idx]);
읽기작업();
LeaveCriticalSection(&m_CS[idx]);


먼저 위처럼 구성했을 경우 _MAX_CS_CNT 만큼 읽기 쓰레드가 접근할 수 있게 됩니다. (엄밀하게는 m_CS_cnt 가 동기화 되지 않아서 idx가 동시에 중복되는 일은 생기지만, 그런 경우에 문제가 생기는 것은 아니라 무시가능하며, 이를 동기화 하는 것이 오히려 비효율 적일 것입니다.)
그리고 쓰기는 아래처럼 구성합니다.

int i;
for(i=0; i<_MAX_CS_CNT; i++)
  EnterCriticalSection(&m_CS[i]);
쓰기작업();
for(i=0; i<_MAX_CS_CNT; i++)
  LeaveCriticalSection(&m_CS[i]);


모든 동기화 객체를 점유한 후에 쓰기작업을 하므로 읽기 작업이 실행될 수 없을 것입니다.
(또한 쓰기 객체끼리 동기화도 먼저 동기화 객체를 점유한 쓰레드만 전부를 가질 수 있기 때문에, 문제가 생기지 않습니다.)

결국 많은 빈도수의 읽기는 동시에 작업이 이루어지며, 쓰기 작업 시에는 읽기 작업이 이루어지지 못하게 됩니다.

예전에는 비슷한 의도를 세마포어객체를 이용해서 처리했었는데, 위처럼 간단하게 처리하는 게 더 맘에 들어서 위의 방식으로 처리하고 있습니다. ( 세마포어를 이용하면 쓰기 객체끼리의 동기화는 별도로 시켜줘야 했었는데, 이 방식이 훨씬 더 단순합니다)

댓글 0

파일 첨부

여기에 파일을 끌어 놓거나 파일 첨부 버튼을 클릭하세요.

파일 크기 제한 : 0MB (허용 확장자 : *.*)

0개 첨부 됨 ( / )
 
목록
번호 제목 글쓴이 날짜 조회 수
64 초간단 VTune 세팅법 [3] 김도완 2005.06.16 1137
63 [공지] 게시판 용도 김도완 2005.06.16 1178
62 파워맥에 들어가는 배터리 단장 2005.06.28 864
61 플래시 메모리 쉽게 끝내기 (1) 단장 2005.07.04 855
60 NOR-플래시 메모리 제어 (2) 단장 2005.07.04 961
59 맥 탄생비화 (1) 단장 2005.07.04 1177
58 AMD CPU 리퍼런스 테이블 단장 2005.07.11 978
57 CPU 평균온도 단장 2005.07.13 1087
56 음식 칼로리표 -_-;;; [3] 단장 2005.07.14 1040
55 Direct3D API들의 실행 사이클 단장 2005.07.15 988
54 순수 탄소 - 퓔러렌 단장 2005.07.19 989
53 오자서 평전 단장 2005.09.26 855
52 귤화위지의 고사 단장 2005.10.03 924
51 비싼 카메라 이야기 단장 2005.11.21 1000
50 니콜라 테슬라 단장 2005.11.26 1168
49 요요회사간의 베어링 규격 단장 2005.12.05 1084
48 원핸드 스트링 기본. 마운트. [1] 단장 2005.12.05 1075
47 아마추어 암호 설계자에게 주는 충고 by 브루스 슈나이어 단장 2005.12.22 983
46 일어 12월명 [1] 단장 2006.03.21 933
45 VC 디버그빌드에서 들어가는 쓰레기값들의 의미 단장 2006.04.15 964