문제

내 시나리오:하나의 서버와 일부 클라이언트(많지는 않지만).서버는 한 번에 하나의 클라이언트에만 응답할 수 있으므로 대기열에 있어야 합니다.나는 뮤텍스를 사용하고 있습니다 (boost::interprocess::interprocess_mutex) 이렇게 하려면 boost::interprocess::scoped_lock.

문제는 한 고객이 예기치 않게 사망하는 경우(예:소멸자가 실행되지 않음) 뮤텍스를 보유하는 동안 다른 클라이언트는 해당 뮤텍스를 기다리고 있기 때문에 문제가 발생합니다.저는 시간 제한 대기를 사용하는 것을 고려했습니다. 따라서 클라이언트가 20초 동안 기다렸다가 뮤텍스를 얻지 못하면 계속해서 서버와 통신합니다.

이 접근 방식의 문제점:1) 매번 이런 일이 발생합니다.루프에 있으면 서버와 지속적으로 통신하므로 매번 시간 초과를 기다려야 합니다.2) 세 개의 클라이언트가 있고 그 중 하나가 뮤텍스를 유지하는 동안 죽으면 나머지 두 개는 20초 동안 기다리면서 동시에 서버와 통신합니다. 바로 이것이 제가 피하려고 했던 것입니다.

그래서, 클라이언트에게 "이 뮤텍스가 버려진 것 같습니다. 소유권을 가져오세요"라고 어떻게 말할 수 있나요?

도움이 되었습니까?

해결책

안타깝게도 이는 Boost::interprocess API에서 있는 그대로 지원되지 않습니다.그러나 이를 구현할 수 있는 몇 가지 방법이 있습니다.

pthread_mutexattr_setrobust_np를 지원하는 POSIX 플랫폼을 사용하는 경우 강력한 뮤텍스를 사용하고 pthread_mutex_lock에서 EOWNERDEAD 반환을 처리하도록 Boost/interprocess/sync/posix/thread_helpers.hpp 및 Boost/interprocess/sync/posix/interprocess_mutex.hpp를 편집하세요. .

다른 플랫폼을 사용하는 경우 Boost/interprocess/sync/emulation/interprocess_mutex.hpp를 편집하여 하위 비트에 잠긴 플래그가 있는 생성 카운터를 사용할 수 있습니다.그런 다음 보류 중인 회수를 나타내기 위해 잠금 워드에 플래그를 설정하는 회수 프로토콜을 생성한 다음, 시간 초과 후 비교 및 ​​교체를 수행하여 동일한 세대가 여전히 잠금 워드에 있는지 확인하고, 그렇다면 교체할 수 있습니다. 고정된 차세대 가치를 갖고 있습니다.

Windows를 사용하는 경우 또 다른 좋은 옵션은 기본 뮤텍스 개체를 사용하는 것입니다.어쨌든 바쁜 대기보다 더 효율적일 것입니다.

공유 메모리 프로토콜의 사용을 재고하고 싶을 수도 있습니다. 대신 네트워크 프로토콜을 사용하는 것은 어떨까요?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top