간단하게 쓰레드, 뮤텍스, 조건 변수 정도만 배워보자!
std::thread
표준 쓰레드다.
이동(move) 가능
복사 불가능
자식 쓰레드가 끝날 때 까지 기다려야한다.
-> thread.join();
-> 쓰레드 개체가 끝날 때까지 현재 쓰레드를 멈춰 놓는다.
-> 이 함수를 호출한 후 쓰레드 개체를 안전하게 소멸시킬 수 있다.
쓰레드의 ID 구하기
std::thread::id childID = thread.get_id();
-> OS마다 ID관리는 다르다.
쓰레드 떼어 내기
thread.detach();
떼어진 쓰레드는 메인 쓰레드와 무관하게 독립적 실행
-> 떼어진 쓰레드는 join 불가능
-> std::thread::joinable()함수를 통하여 쓰레드가 활성 쓰레드인지 아닌지 확인
메인 쓰레드가 죽으면 남은 쓰레드도 죽는다.
std::ref()
const 참조가 아닌 그냥 참조를 전달할 때 사용하면 된다.
T의 참조를 내포한 reference_wrapper 개체를 반환
도우미 함수
std::this_thread
쓰레드 실행 잠시 멈추기
std::this_thread::sleep_for(std::chrono::seconds(시간));
다른 쓰레드에게 양보하기
std::this_yield();
-> sleep과 비슷하나 sleep이 쓰레드를 일시 정지로 바꾸는 반면, yield는 계속 실행 대기 상태
뮤텍스 쓰레딩(Mutex)
1. 공유자원 잠그기
- #include <mutex>
- static std::mutex sMutex;
- sMutex.lock(); => lock은 뮤텍스를 잠근다, 쓰레드에서 두 번 잠그면 데드락 발생(멈춤)
-> 데드락을 허용하기위해선 std::recursive_mutex사용(재귀함수에서 자주 사용
- sMutex.unlock();
lock같은경우 아래 unlock을 해도 함수가 긴 경우 중간에 return이 되어버려서 unlock하지 못하는 경우가 있다.
-> 이에 대하여 std::scoped_lock을 사용하면 좋다 C++17
=> lock이나 unlock을 따로 사용하지말고 std::scoped_lock을 쓰자 (데드락 방지)
- lock은 최소 범위에만 걸자.
조건 변수(이벤트)
std::condition_variable
- 이벤트 개체
- 신호를 받을 때까지 현재 쓰레드의 실행을 멈춤
- notify_one(), notify_all() //멈춘 쓰레드 하나 또는 전부를 다시 실행
- wait(), wait_for(), wait_until() //조건 변수의 조건을 충족시킬 때 까지 또는 일정 시간 현재 쓰레드의 실행 멈춤
- std::unique_lock을 사용해야한다.
std::unique_lock은 기본적으로 scoped lock이다.
생성시 lock을 잠그지 않을 수 있다.(두 번째 매개변수로 std::defer_lcok을 전달)
std::recursive_mutex와 함께 사용하여 재귀적으로 잠글 수 있다.
조건 변수에 유일한 lock이다
std::condition_variable::wait
-> 현재 쓰레드 뮤텍스의 잠금을 풀고 notify_one() 또는 notify_all()을 기다린다.
-> 깨어나면 뮤텍스를 다시 잠근다.
=> notify_xxx()가 wait()보다 먼저 호출되면 해당 쓰레드는 영원히 기다린다.
-> 이에 대한 해결방법 wait의 두번 째 매개변수
조건변수가 신호를 받기 전에 대기 상태에 들어가는 것을 보장할 수 없다면 항상 bool 조건과 lock을 같이 사용할 것
'C++' 카테고리의 다른 글
C++ STL 연산자 오버로딩 (0) | 2022.05.15 |
---|---|
그래픽스 과제 백업 22/04/05 (0) | 2022.04.05 |
모듈 시스템 (0) | 2022.03.04 |
파일 시스템 (0) | 2022.03.04 |
가변 인자 템플릿 (0) | 2022.03.04 |