ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 멀티스레드 Lock구현
    C++/C++ 멀티스레드 2022. 10. 9. 11:21
    728x90

    C++에서 기본적으로 제공하는 mutex, lock_guard 등을 활용하여 멀티스레드 프로그래밍이 가능하지만,

    이것들이 어떻게 구현이 되었는지 간소하게나마 알아보고 직접 구현해보려 한다.

     

    lock은 기본적으로 lock상태와 unlock상태가 있다.

    lock상태라면, 다른 스레드가 lock을 갖지 못하고, 

    unlock상태라면 선착순으로 하나의 스레드에게 lock을 제공할 수 있어야 한다.

     

    그러면 어떤 스레드가 lock을 갖고 사용하고 있을 때 다른 스레드는 lock이 필요로 한다면 어떻게 해야하는가?

     

    저번에는 화장실을 예로 들었지만, 이번에는 헬스장을 예로 들어 보겠다.

     

    나는 헬스를 시작한지 1년정도 되었다.

     

    헬스장에는 피크타임이 있다.

     

    피크타임에 가면, 인기있는 헬스기구들(랫풀다운, 벤치프레스, 스쿼트랙 등)은 언제나 누군가가 사용하고 있다.

     

    그러면 나는 그 기구를 사용하기 위해서 몇 가지 선택을 할 수 있을 것이다.

     

    1. 뒤에 서서 기다린다.

    - 기구를 쓰는 사람이 부담되긴 하겠지만,,, 하도 사람이 많아서 어쩔 수 없다.

     

    2. 다른 기구를 쓰다가 한 번씩 와서 자리가 났는지 확인한다

     

    3. 누군가에게 부탁해서 자리가 나면 알려달라고 한다.

    - 현실에서는 좀 어렵겠지만,,, 예를 들기 위해서

     

    각 방법의 특징에 대해서 알아보자.

    1. 존버메타

    - 그냥 가만~히 뒤에 서서 기다리면 되니까, 움직이는 비용이 들지 않는다.

    -- 움직이는 비용은 Context Switching이라고 한다.

    - 사용하던 사람이 1~2세트밖에 남지 않은 상황이였다면 괜찮은 상황이다.

    -- 물론, 현실에서는 물어보면 되지만 멀티스레드 프로그래밍에서는 얼마나 남았는지 알 수 없다. 예측해야한다.

    - 사용하던 사람이 이제 막 운동을 시작한 상황이라면, 최악의 상황이다. 한~참을 기다려야 한다.

    -- 이 경우, 다른 운동을 할 수 있는 시간을 깎아먹는다. 시간적인 손실이 생기는 것이다.

     

    2. 랜덤메타

    - '예상'되는 운동시간이 긴 경우에 좋은 방법이다.

    - 그 시간에 다른 일을 할 수 있다.

    - 다른 운동기구까지 움직이는 비용(Context Switching)이 발생한다.

    - 운빨이다

    -- 내가 다른 운동을 하는 동안에 자리가 났는데, 나는 뒤에서 기다리고 있지 않으므로,

       다른 사람이 다시 차지해버릴 수도 있다.

    -- 운이 좋으면, 내가 다른 운동을 끝내고 왔을때 바로 내 자리가 날 수 있다.

     

    3. 비서 메타

    - 자리가 나면 바로 사용할 수 있다.

    - 비서를 고용해야한다 = 비용이 든다.

    - Context Switching이 발생한다.

     

    *Context Switching

    • CPU가 현재 처리중인 프로세스를 잠시 중단하고, 다른 프로세스를 실행하게 될 때 일어나는 일이다. 
    • 현재 처리중인 프로세스와 관련된 데이터들이 있을 것인데, 이런 데이터들은 CPU와 가장 가까운 레지스터에 있다.
    • 그런데, 다른 프로세스를 실행해야한다면 그 프로세스가 잠시 멈추던 그 때의 상태로 만들어 줘야 한다.
      1. 현재 작업중인 프로세스와 관련된 데이터를 레지스터에서 메모리로 옮긴다.
      2. 실행하려는 프로세스와 관련된 데이터를 메모리에서 레지스터로 가져온다.
      3. CPU는 아무것도 모른채, 이어서 프로세스와 관련된 작업을 한다.
    • 그러니까 예를 들자면, 숫자를 0부터 100까지 더하는 작업이 있고, 숫자를 101부터 200까지 더하는 작업이 있다고 하자.
    • CPU가 0부터 50까지 더하고 나서 51을 더할 차례인데, 101부터 200까지 더하는 작업을 해야한다면
    • 50까지 더했다는 것과 관련된 데이터를 다른 곳에 잠시 저장해두고
    • 101부터 200까지 더하는 작업이 어디까지 더했는지와 관련된 데이터를 가져와서 이어서 실행해야하는 것이다.

     

    여튼 멀티스레드 환경에서도 스레드가 lock을 기다리는 상황에서 2번 혹은 3번 정책을 선택한다면

    Context Switching이 발생하게 되고, 이에 따른 시간적인 비용이 발생하는 것이다.

    - 하지만 Context Switching이 마냥 배척해야하는 것은 아니다.

     

    다음 포스티에서는 존버메타라고 하는 spin lock을 직접 구현해볼 것이다.

     

    728x90

    'C++ > C++ 멀티스레드' 카테고리의 다른 글

    C++, Sleep을 이용한 Lock구현  (0) 2022.10.10
    C++ SpinLock구현  (0) 2022.10.09
    C++, 멀티스레드 교착상태(DeadLock)  (0) 2022.10.08
    C++ 멀티스레드, lock(mutex)  (1) 2022.10.06
    C++ 멀티스레드, Atomic  (0) 2022.10.05

    댓글

Designed by Tistory.