pthread_cond_wait 대 세마포
사용의 장점과 단점은 무엇입니까?pthread_cond_wait
또는 세마포어를 사용하는가? 다음과 같은 상태 변화를 기다리고 있습니다.
pthread_mutex_lock(&cam->video_lock);
while(cam->status == WAIT_DISPLAY) {
pthread_cond_wait(&cam->video_cond, &cam->video_lock);
}
pthread_mutex_unlock(&cam->video_lock);
올바르게 초기화된 세마포를 사용하면 다음과 같이 할 수 있을 것 같습니다.
while(cam->status == WAIT_DISPLAY) {
sem_wait(&some_semaphore);
}
각 방법의 장점과 단점은 무엇입니까?
세마포는 생산자-소비자 모델에 깔끔하게 적합하지만 다른 용도가 있습니다.프로그램 로직은 대기 횟수에 맞는 게시물이 작성되었는지 확인해야 합니다.세마포를 게시했는데 아직 대기 중인 사람이 없는 경우 대기 중인 경우 즉시 계속됩니다.세마포의 카운트 값으로 설명할 수 있는 문제라면 세마포어로 쉽게 해결할 수 있습니다.
조건변수는 어떤 면에서는 좀 더 관대합니다.예를 들어 cond_broadcast를 사용하여 모든 웨이터를 웨이크업할 수 있습니다.프로듀서는 그 수를 알 수 없습니다.대기자가 없는 상태에서 condvar를 cond_sign 하면 아무 일도 일어나지 않습니다.관심있는 청취자가 있을지 모를 경우 좋습니다.또한 청취자가 대기 전에 항상 뮤텍스를 잡은 상태로 상태를 확인해야 하는 이유이기도 합니다. 그렇지 않으면 신호를 놓치고 다음 신호가 올 때까지 깨어나지 못할 수도 있습니다(그럴 수는 없습니다).
따라서 조건 변수는 mutex 취득, 상태 변경, condvar 시그널링(또는 브로드캐스트) 및 mutex 해제 등 관계자에게 상태가 변경되었음을 통지하는 데 적합합니다.이것이 당신의 문제를 설명한다면 당신은 condvar 영역에 있는 것입니다.서로 다른 청취자가 다른 상태에 관심이 있는 경우, 그냥 방송하면 각 청취자가 차례로 깨어나 원하는 상태를 찾았는지 여부를 확인하고, 다시 기다리지 않으면 다시 확인할 수 있습니다.
뮤텍스와 세마포어를 가지고 이런 종류의 일을 시도하는 것은 정말 괴팍하다.이 문제는 뮤텍스를 가져와 상태를 확인한 후 세마포에서 변경을 기다리는 경우에 발생합니다.mutex를 원자적으로 해제하고 semaphore에서 대기할 수 없는 경우(pthread에서는 대기할 수 없음), mutex를 잡은 상태에서 semaphore에서 대기하게 됩니다.이로 인해 뮤텍스가 차단됩니다.즉, 다른 사용자는 뮤텍스를 사용하여 사용자가 관심을 갖는 변경을 수행할 수 없습니다.따라서 특정 요건에 따라 다른 뮤텍스를 추가하고 싶어질 것입니다.또 다른 세마포도 있겠지그 결과 일반적으로 위험한 레이스 조건이 적용되는 코드가 올바르지 않습니다.
Condition variables escape this problem, because calling cond_wait automatically releases the mutex, freeing it for use by others. The mutex is regained before cond_wait returns.
IIRC it is possible to implement a kind of condvar using only semaphores, but if the mutex you're implementing to go with the condvar is required to have trylock, then it's a serious head-scratcher, and timed waits are out. Not recommended. So don't assume that anything you can do with a condvar can be done with semaphores. Plus of course mutexes can have nice behaviours that semaphores lack, principally priority-inversion avoidance.
Conditionals let you do some things that semaphores won't.
For example, suppose you have some code which requires a mutex, called m
. It however needs to wait until some other thread has finish their task, so it waits on a semaphore called s
. Now any thread which needs m
is blocked from running, even though the thread which has m
is waiting on s
. These kind of situations can be resolved using conditionals. When you wait on a conditional, the mutex currently held is released, so other threads can acquire the mutex. So back to our example, and suppose conditional c
was used instead of s
. Our thread now acquires m
, and then conditional waits on c
. This releases m
so other threads can proceed. When c
becomes available, m
is reacquired, and our original thread can continue merrily along its way.
Conditional variables also allows you to let all threads waiting on a conditional variable to proceed via pthread_cond_broadcast
. Additionally it also allows you to perform a timed wait so you don't end up waiting forever.
Of course, sometimes you don't need conditional variables, so depending on your requirements, one or the other may be better.
The 2nd snippet is racy, don't do that.
The other answers have a nice discussion of the relative merits; I'll just add that pthread_cond_broadcast
is a clear advantage of condition variables.
Beyond that, I'm just more used to condition variables for that, as they are what you use in Java, even because they help you to avoid races when checking the shared flags.
실제로 두 번째 스니펫에는 cam->상태 판독을 보호하는 잠금이 없기 때문에 데이터 레이스를 통해 접근합니다.대부분의 플랫폼에서는 이 예에서는 이 문제를 회피할 수 있지만 POSIX 및 다음 C/C++ 규격의 메모리 모델에 의해 시멘틱스가 정의되지 않았습니다.
실제로 다른 스레드가 새로운 CAM 구조를 할당하여 CAM을 덮어쓰면 실제 레이스 조건이 가능합니다.대기 스레드는 cam-> 상태의 초기화를 인식하지 않고 'cam' 포인터에 대한 업데이트를 확인할 수 있습니다.과연, 2번째의 스니펫은, 이 경우나 일반적인 경우나, 트러블을 요구하고 있습니다.
http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/
두 번째 부분에서는 잠금을 여러 번 받고 절대 해제하지 않습니다.
일반적으로, 당신이 있는 상태는 세마포어로 완전히 표현될 수 있고, 당신은 그것만 사용할 수 있습니다.잠금 구조는 크기가 작고 확인/설정/해제 시 원자적인 조작이 적게 필요합니다.
그 이외의 경우 상태가 복잡하고 코드의 다른 부분이 같은 변수의 다른 조건(여기서는 x<10,여기서는 y>x)에서 대기하고 있는 경우 cond_wait를 사용합니다.
while(cam->status == WAIT_DISPLAY) {
sem_wait(&some_semaphore);
}
이건 완전히 잘못됐어.이것은 레이스 상태에 빠지기 쉽다.sem_Wait 스레드가 블록될 때까지 다른 스레드에서 변경된 상태이기 때문에 cam-> status == WAIT_DISPLAY 상태가 시스템에서 유효하지 않을 수 있습니다.그래서, 당신의 실이 모든 잘못된 이유로 지금 잠자고 있다.
언급URL : https://stackoverflow.com/questions/70773/pthread-cond-wait-versus-semaphore
'source' 카테고리의 다른 글
C에서 1123456789에서 1,123,456,789까지의 숫자를 포맷하려면 어떻게 해야 합니까? (0) | 2022.07.17 |
---|---|
nuxt.js Vuex Vuejs 정의되지 않은 속성 'getters'를 읽을 수 없습니다. (0) | 2022.07.17 |
오류: 유감스럽게도 비 Gradle Java 모듈과 > Android-Gradle 모듈을 하나의 프로젝트에 포함할 수 없습니다. (0) | 2022.07.17 |
uint_fast32_t는 무엇이며 일반 int 및 uint32_t 대신 사용해야 하는 이유는 무엇입니까? (0) | 2022.07.17 |
번들러 없이 Vue를 사용하시겠습니까? (0) | 2022.07.17 |