멀티 스레드 환경에서는 데이터 손상을 방지하기 위해 코드의 중요한 부분을 보호하는 것이 중요합니다. 그러한 중요한 섹션 중 하나는 데이터 대기열 관리입니다. 큐는 FIFO(선입선출) 원칙을 따르는 데이터 구조입니다. C 11에서 스레드로부터 안전한 대기열을 구현하려면 뮤텍스 및 조건 변수와 같은 동기화 메커니즘을 사용하는 것이 필요합니다.
문제의 코드 조각은 std::mutex 및 std::condition_variable을 사용하여 스레드로부터 안전한 대기열을 제공합니다. enqueue 메소드는 큐를 보호하기 위해 qMutex에 잠금을 유지하면서 큐에 항목을 추가합니다. 또한 populatedNotifier 조건 변수를 사용하여 대기 중인 모든 스레드에 알립니다.
dequeue 메소드는 대기열에서 항목을 검색합니다. qMutex에 대한 고유한 잠금을 획득하고 대기열이 비어 있는지 확인하고 필요한 경우 시간 초과와 함께 wait_for 함수를 사용하여 기다립니다. 스레드가 대기열의 새 항목에 대한 알림을 받으면 대기를 종료하고 대기열에서 항목 검색 및 제거를 진행합니다.
그러나 대기열이 비어 있을 때 세그폴트가 관찰되어 wait_for 함수가 반환되었음을 나타냅니다. 통보 없이. 이는 잘못된 wake-up으로 인해 발생할 수 있습니다.
이 문제를 방지하려면 while 루프의 조건을 반전시키는 것이 좋습니다. "큐가 비어 있지 않을 때까지 기다리는 것" 대신 "큐가 비어 있는 동안" 기다리십시오. 이렇게 하면 거짓 깨우기 후 루프가 대기열의 비어 있음을 다시 확인합니다.
다음은 대기열 제거 방법의 수정된 버전입니다.
<code class="cpp">std::string FileQueue::dequeue(const std::chrono::milliseconds& timeout) { std::unique_lock<std::mutex> lock(qMutex); while (q.empty()) { if (populatedNotifier.wait_for(lock, timeout) == std::cv_status::no_timeout) { // Lock may have been released spuriously; recheck condition if (q.empty()) { return std::string(); } std::string ret = q.front(); q.pop(); return ret; } else { return std::string(); } } std::string ret = q.front(); q.pop(); return ret; }</code>
이렇게 하면 스레드가 다음과 같은 경우에만 진행됩니다. 큐가 비어 있지 않아 잘못된 웨이크업으로 인한 세그폴트를 방지합니다.
위 내용은 `std::condition_variable::wait_for`를 사용할 때 C 11 스레드 안전 대기열에서 Segfault를 방지하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!