CodeNote
Coding Note
CodeNote
전체 방문자
오늘
어제
  • 전체 보기 (35)
    • C++ (33)
      • Modern C++ (12)
      • Modern C++ STL (0)
      • Thread (16)
      • Thread (Async) (5)
    • 디자인패턴 (0)
    • Algorithm (2)
    • Electron (0)
    • Python (0)

블로그 메뉴

  • 홈
  • Github
  • 태그
  • 방명록

공지사항

인기 글

태그

  • LOCK
  • C++ #Memory
  • 자료구조
  • C++
  • Free
  • mutex

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
CodeNote
C++/Thread

[Thread] std::latch

[Thread] std::latch
C++/Thread

[Thread] std::latch

2022. 8. 9. 22:04

std::latch (C++20)

latch는 문고리라는 뜻인데 일정 조건을 만족하면 문고리가 열리면서 wait 상태였던 쓰레드들이 자신들의 일을 계속 수행할 수 있다. latch는 카운터 베이스이기 때문에 세마포어와 비슷하다고 생각할 수 있지만 세마포어와 다르게 latch는 카운터가 감소하기만하는 특징을 가지고 있다. cppreference를 보면 latch는 카운트를 reset하거나 증가시키는 방법은 없다고 정의되어있다.

 

latch의 초기 카운트가 2라고 가정하였을 경우

쓰레드들이 일을 수행하는데 처음 latch의 count_down() 함수를 통해 카운트가 1로 감소하고 wait()함수를 통해 해당 쓰레드는 block이 된다.

이 후 다른 쓰레드가 진행되면서 count_down()을 하면 latch의 카운트는 0이 되고, 카운트가 0이 되면서 block되었던 쓰레드가 깨어나서 자신의 일을 진행하게 된다. 이어서 count_down()을 마지막으로 호출한 쓰레드가 wait()함수를 호출하여도 이 때 카운트는 0이기 때문에 block에 빠지지 않고 자신의 일을 계속 수행하게된다.

 

정리하자면 latch의 count_down() 함수는 latch 카운트를 1 감소시키고 wait() 함수는 카운트가 0이 아닐 때는 쓰레드를 block 상태로 만들고 0일 때는 자신의 일을 계속 수행한다. 또한, latch를 통해 block이 된 쓰레드들은 카운트가 0이 되는 순간 다시 깨어나서 자신의 일을 진행한다.

 

Example Code

#include <iostream>
#include <thread>
#include <chrono>
#include <latch>
#include <vector>

std::latch latch{3};

void fn()
{
    std::cout << "decrease counter" << std::endl;
    latch.count_down();
    std::cout << "wait" << std::endl;
    latch.wait();
    std::cout << "rerun" << std::endl;
}

int main()
{
    std::vector<std::thread> threads;
    for (int i = 0; i < 3; i++) // 쓰레드 3개 생성
    {
        using namespace std::literals;
        std::this_thread::sleep_for(500ms);
        threads.emplace_back(std::thread(fn));
    }

    for (auto& thread : threads)
    {
        thread.join();
    }

    return 0;
}

출력 결과

예상한대로 처음 2개의 thread는 wait 상태로 넘어갔다가 깨어나고 마지막 thread는 카운트가 0인 상태에서 wait를 호출했기 때문에 바로 rerun이 출력되었다. 여기서 주의할 점이 있는데 latch는 카운트의 개수를 reset할 수 없다는 것이다. 이미 latch의 카운트가 0인데 count_down()을 한 번 더 호출한다면 0이었던 카운트가 -1(음수)이 되고 그 이후부터는 block이 된 쓰레드들이 다시 깨어날 수가 없다.

 

Example Code

#include <iostream>
#include <thread>
#include <chrono>
#include <latch>
#include <vector>

std::latch latch{3};

void fn()
{
    std::cout << "decrease counter" << std::endl;
    std::cout << "wait" << std::endl;
    latch.arrive_and_wait(); // count_down()과 wait() 함수를 결합한 함수
    std::cout << "rerun" << std::endl;
}

int main()
{
    std::vector<std::thread> threads;
    for (int i = 0; i < 4; i++)
    {
        using namespace std::literals;
        std::this_thread::sleep_for(500ms);
        threads.emplace_back(std::thread(fn));
    }

    for (auto& thread : threads)
    {
        thread.join();
    }

    return 0;
}

출력 결과

그러니까 위와 같이 latch 카운트는 3이지만 4개의 쓰레드를 돌리게 된다면 마지막 하나의 쓰레드는 영원한 wait 상태에 빠지게 된다. 

 

'C++ > Thread' 카테고리의 다른 글

[Thread]semaphore  (0) 2022.07.26
[Thread] Producer-Consumer 패턴  (0) 2022.07.26
[Thread] Condition Variable  (0) 2022.07.23
[Thread] scoped static 초기화  (0) 2022.07.19
[Thread] std::call_once  (0) 2022.07.18
  • std::latch (C++20)
'C++/Thread' 카테고리의 다른 글
  • [Thread]semaphore
  • [Thread] Producer-Consumer 패턴
  • [Thread] Condition Variable
  • [Thread] scoped static 초기화
CodeNote
CodeNote
기록 블로그

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.