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

2007.09.29 02:32

단장 조회 수:3284 추천: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개 첨부 됨 ( / )
 
목록
번호 제목 글쓴이 날짜 조회 수
44 [C++] extern C에 대해 단장 2007.05.01 1256
43 형법총론 핵심정리 단장 2006.04.19 1246
42 네크로노미콘 단장 2006.10.27 1234
41 [공지] 게시판 용도 김도완 2005.06.16 1178
40 맥 탄생비화 (1) 단장 2005.07.04 1177
39 니콜라 테슬라 단장 2005.11.26 1168
38 윈도우에서 사용하는 포트들 단장 2007.09.06 1157
37 일본어 날짜 단장 2008.02.19 1150
36 평 <-> 평방미터 도량형 환산. 단장 2007.08.24 1146
35 초간단 VTune 세팅법 [3] 김도완 2005.06.16 1137
34 개인적으로 만들어 본 리눅스 게임 서버 FAQ 단장 2007.11.27 1125
33 원진살 단장 2007.04.14 1092
32 CPU 평균온도 단장 2005.07.13 1087
31 요요회사간의 베어링 규격 단장 2005.12.05 1084
30 원핸드 스트링 기본. 마운트. [1] 단장 2005.12.05 1075
29 음식 칼로리표 -_-;;; [3] 단장 2005.07.14 1040
28 Mercedes-Benz, BMW, Audi 단장 2007.01.20 1030
27 비싼 카메라 이야기 단장 2005.11.21 1000
26 순수 탄소 - 퓔러렌 단장 2005.07.19 989
25 Direct3D API들의 실행 사이클 단장 2005.07.15 988