멀티스레드에서 std::map 을 공유자원으로 사용 할 때 궁금한 것이 있습니다.
글쓴이: trade1532 / 작성시간: 화, 2012/01/17 - 11:53오전
ObjectMap이라는 std::map 타입의 객체가 있고 INT와 Object*를 쌍으로 관리합니다.
이 객체는 여러 스레드에서 추가하고 제거하고 조작하는데, ObjectMap에 동기화를 해 줘야겠지요.
ObjectMap에 담긴 Object*객체들을 사용할 때 INT키를 통해서 find하여 사용합니다.
그런데 find해서 사용하는 도중 다른 스레드가 ObjectMap에서 그 해당 객체를 제거해 버릴 수 있으니
find해서 객체를 사용하는 작업까지 ObjectMap을 동기화 시켜줍니다.
이렇게 되면 만약 ObjectMap에 Object* a, Object* b 두 포인터가 저장되어 있다고 할 때
a를 find해서 사용할 때 ObjectMap이 락이 걸려 있어 다른 스레드에서 b에 접근하기 위해서는 기다려야 합니다.
a와 b는 아무런 관계가 없는데도 말이죠..
객체를 추가/제거하는 작업보다 find하는 일이 빈번하게 있을 경우 이것은 너무 비효율적으로 작동하는것 같습니다.
다른 해결방법이 없나요?
Forums:
SlimReaderWriter락 같은 것을
SlimReaderWriter락 같은 것을 고려해보세요.
여러 위치에서 읽기만 하는 경우에는 동시에 접근 가능하도록 하고 쓰기가 있을 때만 다른 놈들이 못들어오게 잠그는 방법입니다.
윈도우에는 따로 api가 제공되고 있는데 사용방법을 참조하셔서 구현을 하시거나 다른 라이브러리를 찾아보셔도 되겠네요.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937(v=vs.85).aspx
아 ...
Find를 std::map 입장에서는 읽기에 해당되니
SRW쓰면 효율이 올라가겠군요.
a를 find해서 사용할 때 ObjectMap이 락이
정확히 말하자면, 아무관계가 없는것은 아닙니다.
find을 할때, ObjectMap에 있는 모든 노드가 용의자가 되어버립니다.
find함수의 입장에서는,
뒤져서 결과를 얻기전까지, a와 b가 같은노드인지 아닌지 알수가 없기에, ObjectMap에 속한 모든 용의자들을 불러서 비교해보고 찾습니다.( 참고로, STL의 대부분의 std::map은 red-black tree를 이용하여 구현되어 있습니다. )
그렇기때문에, find()를 하는동안, add나 delete를 하면 문제가 생깁니다.
수사하고있는데, 범인찾기도전에 누가 맘대로 용의자들을 넣고빼고하면 짜증나죠.
누군가를 빼거나, 넣고 싶으면, 용의자들 조사 다 끝낸후에 하라고 하겠죠.
댓글 달기