일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 암시적 변환
- virtual function
- 영화 리뷰
- 상속
- 함수 객체
- exception
- Smart Pointer
- implicit conversion
- reference
- 다형성
- lua
- 비교 함수 객체
- Effective c++
- 티스토리챌린지
- more effective c++
- 참조자
- operator new
- 스마트 포인터
- c++
- 영화
- 예외
- 게임
- 언리얼
- 반복자
- effective stl
- 메타테이블
- 루아
- resource management class
- UE4
- 오블완
Archives
- Today
- Total
스토리텔링 개발자
[Effective STL] 12. 쓰레드 안전성 본문
728x90
항목 12. STL 컨테이너 쓰레드 안전성에 대한 기대는 현실에 맞추어 가지자
다중 쓰레딩을 지원하는 STL의 동작
- 여러 쓰레드에서 읽는 것은 안전하다.(Multiple readers are safe)
- 여러 쓰레드에서 다른 컨테이너에 쓰는 것은 안전하다.(Multiple writers to different containers are safe)
- SGI(실리콘 그래픽스사) STL이 이를 지원했다.
- 허나 현재 와서는 개발이 중단되었다..
컨테이너의 완벽한 쓰레드 안전성 구현을 위해 라이브러리에서 해야할 것
- 컨테이너의 멤버 함수를 호출하는 시간 동안에 컨테이너에 락(lock)을 걸기
- 컨테이너가 만들어 내어 주는 반복자의 유효 기간 동안에 컨테이너에 락을 걸기
- 컨테이너에 대해 실행된 알고리즘의 수행 시간 동안에 컨테이너에 락을 걸기
- 알고리즘은 자신이 조작하고 있는 컨테이너를 식별할 방법이 없으므로 사실상 불가능하다.(항목 32 참조)
라이브러리가 쓰레드 안전성을 챙기는 것의 어려움
vector<int> v;
...
// 처음 찾은 5를 0으로 바꾸는 코드
vector<int>::iterator first5(find(v.begin(), v.end(), 5)); // 실행줄 1
if(first5 != v.end()) // 실행줄 2
{
*first5 = 0; // 실행줄 3
}
- 실행줄 1 이후, 다른 쓰레드가 v를 바꿔버릴 수 있다.
- 기존 반복자가 무효화될 것이다.(항목 14 참조)
- 실행줄 2에서 정의되지 않은 실행결과(시스템 다운, 프로그램 다운)가 발생한다.
- 실행줄 3의 대입문 역시 마찬가지로 무효화 시 문제가 발생한다.
- 그렇다면 앞의 세 가지 '락 걸기'로 이 문제를 막을 수 있을까?
- 실행줄 1에 락을 건다면?
- 해당 줄만 쓰레드 안전성을 보장해봤자, 실행 이후에는 동일한 문제가 발생한다.
- 결국 락을 걸려면 실행줄 전부에 락을 걸 수 있어야 한다.
- 헌데 이것을 STL 구현에서 보장해줄 수 있을까?
- 보장한다 쳐도 심각한 수행 성능 저하가 발생할 것이다.
- 실행줄 1에 락을 건다면?
- 즉, 사용자가 쓰레드 동기화를 제어하는 것이 낫다.
vector<int> v;
...
getMutexFor(v);
vector<int>::iterator first5(find(v.begin(), v.end(), 5));
if(first5 != v.end())
{
*first5 = 0;
}
releaseMutexFor(v);
- RAII를 사용하여 좀 더 객체지향적으로 바꾼 버전
// RAII로 간편화
template<typename C>
class Lock
{
public:
Lock(const C& container) : c(container)
{
getMutexFor(c);
}
~Lock()
{
releaseMutexFor(c);
}
private:
const C& c;
};
vector<int> v;
...
{
Lock< vector<int> > lock(v); // 뮤텍스 획득
vector<int>::iterator first5(find(v.begin(), v.end(), 5));
if(first5 != v.end())
{
*first5 = 0;
}
} // 범위를 벗어나며 뮤텍스 해제
- 이 경우 예외에도 안전하다. 예외 발생으로 범위를 벗어난다면 자동으로 해제가 될 것이기 때문이다.
참고
728x90
'개발 > Effective STL' 카테고리의 다른 글
[Effective STL] 14. vector reserve (0) | 2024.11.21 |
---|---|
[Effective STL] 13. 배열보다 vector (0) | 2024.11.20 |
[Effective STL] 11. 커스텀 할당자(Custom Allocator) (0) | 2024.11.18 |
[Effective STL] 10. 할당자(Allocator)의 제약 사항 (1) | 2024.11.14 |
[Effective STL] 9. 컨테이너별 요소 삭제 (0) | 2024.11.13 |
Comments