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

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개 첨부 됨 ( / )
 
목록
번호 제목 글쓴이 날짜 조회 수
24 [공지] 게시판 용도 김도완 2005.06.16 1178
23 네크로노미콘 단장 2006.10.27 1234
22 형법총론 핵심정리 단장 2006.04.19 1246
21 [C++] extern C에 대해 단장 2007.05.01 1256
20 Stream of Life 단장 2009.06.29 1285
19 NAT 홀펀칭 단장 2007.10.25 1294
18 [C++]function objects 단장 2007.05.01 1341
17 한국운전면허를 일본운전면허로 바꾸기 [2] 단장 2007.10.26 1351
16 이스람(Islam:회교:回敎)에서의 성 단장 2007.02.08 1379
15 제트 추력 엔진 단장 2008.04.29 1600
14 Nat기반 P2P 프로그래밍 단장 2007.11.21 1627
13 자동차 정비용어 정리 단장 2007.01.20 1660
12 골프의 물리학 단장 2009.05.30 1681
11 std::tr1 단장 2008.03.13 1848
10 Fast Bit Counting 단장 2009.02.21 1883
9 Large Address Aware file 단장 2014.03.05 1948
8 술의 이력서 단장 2007.02.09 2270
7 vTune 사용법 단장 2009.01.13 3234
» 효율적인 동기화를 위한 아이디어 하나 단장 2007.09.29 3284
5 버텍스버퍼의 효율적인 사용 단장 2007.10.01 5100