Heim > Backend-Entwicklung > C++ > Hauptteil

Warum erhalte ich Segfaults, wenn ich eine Bedingungsvariable verwende, um in C nach einer leeren Warteschlange zu suchen?

Linda Hamilton
Freigeben: 2024-10-31 21:14:29
Original
654 Leute haben es durchsucht

Why Am I Getting Segfaults When Using a Condition Variable to Check for an Empty Queue in C  ?

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>
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!