작성
·
324
1
wait에서 두 번째 매개변수로 람다식을 넣어주셨는데요! 영상으로는 15분 01초 정도입니다.
이게 람다식 넣어줘서 다시 검사하자는 논리는 이해하겠는데,
lock같은 경우 Lock기초 편에서 t1과 t2가 동시에 lock을 걸었고, t1이 간발의 차로 얻은 상황이면 t2는 t1이 unlock을 호출할 때까지 대기한다고 설명을 들었는데, 애초에 대기를 한다면 cv.wait 코드가 있는 줄로 못넘어가는 것이 아닌가 생각되는데... 제가 어디서 잘못 생각했을까요?
답변 1
1
제가 변수 이름을 lock으로 지어서
m.lock();
m.unlock();
케이스랑 혼동하신 것 같네요
위에서 unique_lock 객체를 만들어주고 있고,
unique_lock 객체가 소멸되면
알아서 락이 풀리는 일종의 lock_guard이기 때문에,
언젠가는 뮤텍스를 획득할 수 있게 됩니다.
상대방이 락을 놔주면 이쪽에서 잡아서 wait로 실행하게 되는 것이죠.
unique_lock을 사용하는 이유는, 단순하게 condition_variable이 인자로 unique_lock을 받기 때문입니다. unique_lock은 일반 lock_guard와 다르게, mutex를 직접 lock하고 unlock하는 기능들이 있습니다. 그것을 condition_variable 코드 내부에서 사용해서 lock / unlock을 해주게 됩니다.
(unique_lock에 의해 lock이 잡힌 상태에서, cv.wait 조건을 만족하지 않으면 unlock을 하는 등)
즉, condition_variable은 별도로 생각하면 안되고 걔도 내부적으로 lock/unlock에 개입한다고 생각해야 합니다.
아 혹시 unique_lock은 그냥 defer_lock 값을 안 주면 바로 락을 거는게 아닌가요?
지금까지 unique_lock이 매개변수로 뮤텍스 하나만 받으면 그냥 락가드랑 동일하다고 생각하고 있었는데 여기가 잘못됐군요..!
아 답변을 다시 보고 이해했습니다..! 조건식 불일치시 cv가 걸어뒀던 lock을 풀어버려서 lock을 기다리던 다른 consumer 중 승자가 lock을 획득하게 되는 것이네요..! 조건식 일치시 lock을 풀지 않고 코드 진행시켜서 생명주기에 맞게 자동으로 lock이 풀리고
조건식 불일치 직후 producer가 아닌 consumer중 하나가 CPU를 얻고, lock을 획득했다고 하면, 어차피 또 조건식 불일치니까 또 sleep...
producer보다 먼저 cpu를 획득하는 모든 consumer들은 하나씩 하나씩 sleep하게 되고, producer가 push하고 notify하고 나면 CPU를 획득한 consumer가 다시 pop하고..
답변 감사드립니다!
유니크락에 두 번째 매개변수를 안 주면 락가드랑 동일하니까, 굳이 유니크락을 쓸 필요가 없는데 유니크락을 사용하라고 하신 측면에서 생각해봤는데, 유니크락에 두 번째 매개변수로 defer_lock을 주고 난 뒤 일단 cv.wait까지 실행시키고 난 뒤, notify_one으로 한 놈이 깨어나면 아래 코드 블록에 lock.lock()을 호출해주는 것이 원래 의도로 생각되는데...
여러명의 consumer가 있고, 락가드로 접근한다면 경합에서 이긴 1명의 consumer를 제외한 나머지 consumer들은 애초에 wait로 빠져나갈 수 없기 때문에 q.empty()==false는 항상 true를 리턴해서 검사할 의미가 없지만, 나머지 consumer들을 sleep시키려고 일련의 코드를 작성했기 때문에 락가드는 사용할 의미가 없고 유니크락을 defer_lock값을 줘서 일단 경합에서 진 친구들을 다 재우기 위한 방법으로 유니크락을 사용했다고 봐도 될까용?