In einer Multithread-Umgebung ist es wichtig sicherzustellen, dass kritische Codeabschnitte geschützt sind, um Datenbeschädigungen zu verhindern. Ein solcher kritischer Abschnitt ist die Verwaltung von Datenwarteschlangen. Eine Warteschlange ist eine Datenstruktur, die dem Prinzip „First-In, First-Out“ (FIFO) folgt. Die Implementierung einer Thread-sicheren Warteschlange in C 11 erfordert die Verwendung von Synchronisationsmechanismen wie Mutexes und Bedingungsvariablen.
Der betreffende Codeausschnitt stellt eine Thread-sichere Warteschlange mit std::mutex und std::condition_variable dar. Die Enqueue-Methode fügt der Warteschlange ein Element hinzu und hält gleichzeitig eine Sperre für den qMutex aufrecht, um die Warteschlange zu schützen. Darüber hinaus werden alle wartenden Threads über die Bedingungsvariable populatedNotifier benachrichtigt.
Die Dequeue-Methode ruft ein Element aus der Warteschlange ab. Es erhält eine eindeutige Sperre für den qMutex, prüft, ob die Warteschlange leer ist, und wartet mit der Funktion „wait_for“ bei Bedarf mit einem Timeout. Wenn ein Thread über neue Elemente in der Warteschlange benachrichtigt wird, verlässt er die Wartezeit und fährt mit dem Abrufen und Entfernen eines Elements aus der Warteschlange fort.
Es wurden jedoch Segfaults beobachtet, wenn die Warteschlange leer war, was darauf hindeutet, dass die Funktion „wait_for“ zurückgegeben wurde ohne Benachrichtigung. Dies kann auf ein falsches Aufwecken zurückzuführen sein.
Um dieses Problem zu verhindern, empfiehlt es sich, die Bedingung für die While-Schleife umzukehren. Anstatt „zu warten, bis die Warteschlange nicht leer ist“, warten Sie, bis „die Warteschlange leer ist“. Dadurch wird sichergestellt, dass die Schleife nach jedem falschen Aufwachen erneut überprüft, ob die Warteschlange leer ist.
Hier ist eine überarbeitete Version der Dequeue-Methode:
<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>
Dadurch wird sichergestellt, dass der Thread nur fortfährt, wenn Die Warteschlange ist nicht leer, wodurch Segfaults durch falsches Aufwecken vermieden werden.
Das obige ist der detaillierte Inhalt vonWie verhindert man Segfaults in einer Thread-sicheren C 11-Warteschlange bei Verwendung von „std::condition_variable::wait_for'?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!