스레드는 한 프로세스 안에서 동시에 진행하는 실행 흐름이다. 두 스레드가 동기화 없이 같은 메모리를 쓰고, 그중 하나라도 수정하면 데이터 경합이다. 데이터 경합은 미정의 동작이다.
수명과 잠금
#include <mutex>
#include <thread>
std::mutex mu;
int games = 0;
void add_one() {
std::lock_guard<std::mutex> lock{mu};
++games;
}`std::thread`는 소멸 전에 `join`하거나 `detach`해야 한다. 둘 다 하지 않으면 소멸자가 프로그램을 종료한다. `detach`한 스레드는 객체가 죽은 뒤를 쉽게 건드린다. C++20의 `std::jthread`는 소멸 때 join을 대신해 준다.
교착
두 뮤텍스를 스레드마다 반대 순서로 잡으면 서로 기다리다 멈춘다. 여러 뮤텍스는 `std::scoped_lock`으로 한 번에 잡아 순서를 고정한다. 조건 변수는 반드시 `unique_lock`과 함께 쓰고, `wait`는 조건을 다시 확인하는 루프 안에서 깨운다. 깨움은 위조될 수 있다.
연산이 락 안에서 오래 끌수록 다른 스레드는 멈춘다. 락 안에서는 공유 상태를 짧게 만지고, 계산은 밖으로 뺀다.
댓글
0개아직 댓글이 없습니다.