본문 바로가기
728x90

multithread5

[MultiThread] Event, Condition Variable ■ 스핀락, 일반 Lock, 이벤트 · 앞서 배운 예제로 Spinlock은 기내 화장실 앞에서 죽치고 쭈욱 기다리는 것이고, 일반 Lock은 내 자리에 돌아갔다가 다시 화장실이 빌 것 같을 때 자리가 있는지 확인하러 오는 방식이다. · 이벤트 방식은 승무원에게 화장실이 비게 되면 알려달라고 부탁한 뒤 우리는 자리로 가서 대기하는 것이다. ■ 사용법 (1) #include 헤더를 추가한다. (2) HANDLE 타입의 변수를 선언한다. - 여태까지 변수 선언을 하면 유저레벨에서 관리를 하던 변수들이었지만 - Handle은 운영체제가 관리하는 오브젝트를 만들어주게끔 요청할 수 있는 커널 오브젝트(Kernel Object)이다. 커널 오브젝트 (Kernel Object) 구성 요소 모든 커널 오브젝트는 사용되어.. 2024. 4. 8.
[MultiThread] Mutex, Spinlock, DeadLock ■ atomic의 한계 변수 하나만을 보호한다는 한계가 있음. 즉, 함수 내에 여러 공유 변수 전체를 보호할 수 없음. 또한 변수를 보호하더라도 load, store와 같이 대입 및 저장 같은 단순한 연산을 보호하는 것이고 동적할당을 하며 메모리를 옮겨다니는 벡터와 같은 컨테이너는 100% 보호 가능하다는 보장을 할 수가 없음. ■ 동적 할당에서의 멀티쓰레딩 아래 코드를 동작시키면 크래쉬가 발생한다. 그 이유는 앞서 배운 벡터의 원리를 생각하면 이해가 된다. Capcity를 들고있는데 Size가 Capacity와 같아진다면 벡터는 더 넓은 capacity를 차지하기 위해 모든 메모리를 이사시킨다. 이때 다른 쓰레드가 벡터에 접근하게 된다면 이사하고나서 메모리 주소가 바뀌었음에도 불구하고 이제는 사용하지 .. 2024. 4. 8.
[MultiThread] 공유 자원, Atomic ■ 공유데이터 사용 시 발생할 수 있는 문제 상황 아래와 같이 코드를 작성해봤다. 이를 실행 했을 때 결과값은 어떻게 될까? 논리적으로 생각하면 아래와 같이 0이 되어야 한다. 하지만 만약 백만번씩 실행한다고 했을 때 여전히 우리가 생각하는대로 0이 될까? 이를 코드 수정 후 확인해보면 아래와 같이 엉뚱한 값이 나오는 것을 볼 수 있었다. 위에서 공유 영역인 Data영역에 sum 변수가 할당되었다. 이 공유 영역에 할당된 sum 변수를 thread1과 thread2가 같이 사용하기 때문에 발생한 문제이다. 아무리 그래도 더하고 빼는 횟수는 같아야할 텐데 이러한 문제는 왜 발생하는가? 이유는 어셈블리를 까보면 ++ 혹은 --하는 코드는 아래 세 단계로 이루어져 있기 때문이다. [int operator++ .. 2024. 4. 7.
[MultiThread] 캐시 및 CPU 명령어 파이프라인 ■ CPU와 RAM 왔다갔다 계속 사용하기엔 시간이 다소 많이 소요되니 이 둘 사이에 저장공간인 레지스터 및 캐시를 이용한다. [CPU 코어 구성] (1) ALU (연산장치) (2) 캐시 장치 - 레지스터 - L1 캐시 - L2 캐시 .... 캐시 장치를 구성하는 레지스터, L1캐시, L2캐시는 계층 구조로 생각해봤을 때 아래로 갈수록 (Register->L2) 저장 공간은 많아지지만 속도는 느려진다. 위 캐시 장치들을 모두 훑어봤을 때도 데이터가 없을 경우에 주기억장치로 가서 훑어보게 된다. ■ 캐시 정책 지역성 설명 시간지역성 (Temporal Locality) (레스토랑 비유) 시간적으로 보면, 방금 주문한 테이블에서 추가 주문이 나올 확률이 높다. 방금 주문한걸 메모해 놓으면 편하지 않을까? 공간.. 2024. 4. 7.
[MultiThread] 쓰레드 생성 ■ C++ 11 이전 및 이후 이전에는 각 운영체제마다 제공하는 함수가 다르기 때문에 문서를 찾아보고 해야했다. 하지만, C++ 11(모던C++)이후 부터는 쓰레드 생성이 표준에 추가되어 #include 를 통해 굉장히 편리하게 스레드를 만들 수 있게 되었다. ■ 사용 법 (1) #include 헤더를 추가한다. (2) 일반적인 변수를 선언하듯이 std::thread t; 와 같이 스레드를 선언한다. (3) 다만, Thread가 처음 실행되는 순간에는 실행이 되어야 하는 함수를 우리가 넣어줘야 한다. (4) 하지만 위 코드를 그대로 사용하면 크래쉬가 난다. 그 이유는 - 메인 스레드가 종료가 되었는데 자식 스레드가 끝나지 않았기 때문에 크래쉬가 일어난다. - 그러므로 메인 스레드는 자식 스레드가 끝날 때.. 2024. 4. 7.
728x90