C 11 Thread-sichere Warteschlange: Verwirrung über die Verwendung von Bedingungsvariablen
In Ihrem Code haben Sie eine Thread-sichere Warteschlange mithilfe eines Mutex implementiert und eine Bedingungsvariable. Allerdings treten gelegentlich Segfaults innerhalb des Codeblocks auf, der von der Bedingungsvariablen gesteuert wird. Insbesondere stellen Sie fest, dass die Segfaults auftreten, wenn die Warteschlange leer ist, was kontraintuitiv erscheint, da die Bedingungsvariable die Verfügbarkeit neuer Elemente in der Warteschlange signalisieren soll.
Falsche Verwendung der Bedingungsvariablen
Ihr Missverständnis ist auf die falsche Verwendung der Bedingungsvariablen zurückzuführen. Der Zweck einer Bedingungsvariablen besteht darin, eine Änderung eines gemeinsamen Zustands zu signalisieren, sodass andere Threads dann auf diese Änderung reagieren können. In Ihrem Code verwenden Sie jedoch die Bedingungsvariable, um darauf zu warten, dass eine bestimmte Bedingung (die Warteschlange ist leer) falsch wird. Das ist falsch, denn wenn die Bedingung falsch wird (d. h. die Warteschlange ist nicht mehr leer), wird der Thread aufwachen, aber es ist nicht garantiert, dass die Bedingung falsch bleibt (d. h. die Warteschlange könnte in der Zwischenzeit wieder leer geworden sein). .
Richtige Verwendung von Bedingungsvariablen
Die korrekte Verwendung einer Bedingungsvariablen besteht darin, eine Schleife zu verwenden, die die Bedingung prüft (in diesem Fall, ob die Warteschlange leer ist). ) und geht in einen Wartezustand über, wenn die Bedingung nicht erfüllt ist. Wenn die Bedingung signalisiert wird, wird der Thread aktiviert, prüft die Bedingung jedoch sofort erneut, bevor er fortfährt. Dadurch wird sichergestellt, dass der Thread nur dann die gewünschte Operation ausführt, wenn die Bedingung beim Aufwachen immer noch wahr ist.
Alternative Implementierung
Hier ist eine alternative Implementierung eines Thread-Safe Warteschlange, die das Problem behebt:
<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>
In dieser Implementierung wird die Bedingungsvariable korrekt verwendet, um darauf zu warten, dass die Bedingung, dass die Warteschlange leer ist (oder nicht leer für die Enqueue-Methode), falsch wird. Der Thread führt den gewünschten Vorgang (Entfernen eines Elements aus der Warteschlange) nur aus, wenn die Warteschlange nach dem Aufwachen nicht leer ist.
Das obige ist der detaillierte Inhalt vonWarum erhalte ich Segfaults, wenn ich eine Bedingungsvariable verwende, um in C nach einer leeren Warteschlange zu suchen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!