C 11 스레드 안전 대기열: 조건 변수 사용에 대한 혼란
코드에서 뮤텍스를 사용하여 스레드 안전 대기열을 구현했습니다. 그리고 조건변수. 그러나 조건 변수에 의해 제어되는 코드 블록 내에서 가끔 세그폴트가 발생합니다. 특히 대기열이 비어 있을 때 세그폴트가 발생한다는 점을 발견했습니다. 이는 조건 변수가 대기열에 새 항목이 있음을 알리기 위한 것이므로 직관에 반하는 것처럼 보입니다.
잘못된 조건 변수 사용
귀하의 오해는 조건변수의 잘못된 사용에서 비롯되었습니다. 조건 변수의 목적은 공유 상태의 변경을 알리는 것입니다. 그러면 다른 스레드가 이 변경에 반응할 수 있습니다. 그러나 코드에서는 조건 변수를 사용하여 특정 조건(큐가 비어 있음)이 false가 될 때까지 기다립니다. 조건이 false가 되면(즉, 큐가 더 이상 비어 있지 않음) 스레드가 깨어나지만 조건이 false로 유지된다는 보장은 없기 때문에 이는 잘못된 것입니다(즉, 그 동안 큐가 다시 비어 있을 수 있음). .
적절한 조건 변수 사용법
조건 변수를 활용하는 올바른 방법은 조건을 확인하는 루프를 사용하는 것입니다(이 경우 대기열이 비어 있는지 여부). ) 조건이 충족되지 않으면 대기 상태로 들어갑니다. 조건이 신호되면 스레드가 깨어나지만 진행하기 전에 즉시 조건을 다시 확인합니다. 이렇게 하면 깨어났을 때 조건이 여전히 참인 경우에만 스레드가 원하는 작업을 수행할 수 있습니다.
대체 구현
다음은 스레드로부터 안전한 대체 구현입니다. 문제를 해결하는 대기열:
<code class="cpp">template <class T> class SafeQueue { public: SafeQueue() : q(), m(), cv() {} void enqueue(T t) { std::lock_guard<std::mutex> lock(m); q.push(t); cv.notify_one(); } T dequeue() { std::unique_lock<std::mutex> lock(m); while (q.empty()) cv.wait(lock); T val = q.front(); q.pop(); return val; } private: std::queue<T> q; mutable std::mutex m; std::condition_variable cv; };</code>
이 구현에서 조건 변수는 대기열이 비어 있는(또는 대기열에 넣기 방법의 경우 비어 있지 않음) 조건이 false가 될 때까지 기다리는 데 올바르게 사용됩니다. 스레드는 깨어난 후 대기열이 비어 있지 않은 경우에만 원하는 작업(항목 대기열 제거)을 수행합니다.
위 내용은 C에서 빈 대기열을 확인하기 위해 조건 변수를 사용할 때 왜 Segfault가 발생합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!