Es hängt davon ab, was Sie erwarten. Die anderen Antworten sind richtig, dass im Allgemeinen, C++ - Standardcontainer sind nicht thread-sicher, und außerdem, dass insbesondere Ihr Code nicht gegen einen anderen Thread die Änderung des Containers zwischen Ihrem Anruf an empty
und den Erwerb der Schloss (aber diese Angelegenheit hat nichts mit der Gewindesicherheit von vector::empty
zu tun).
Also, um Missverständnisse abzuwenden: Ihr Code garantiert nicht items
wird nicht leer innerhalb des Blocks.
Aber Ihr Code kann immer noch nützlich sein, da Sie nur redundante Lock-Kreationen vermeiden wollen. Ihr Code gibt keine Garantien, aber es kann verhindern eine unnötige Sperre erstellen. Es funktioniert nicht in allen Fällen (andere Threads können immer noch den Container zwischen Ihrem Scheck und der Sperre leeren), aber in einige Fälle. Wenn Sie nur nach einer Optimierung suchen, indem Sie eine redundante Sperre ausschließen, erreicht Ihr Code dieses Ziel.
So stellen Sie sicher, dass jeder tatsächliche Zugang zum Behälter durch Sperren geschützt ist.
By the way, die oben ist streng genommen undefinierten Verhalten: eine STL-Implementierung theoretisch mutable
Mitglieder innerhalb der Anruf erlaubt ist empty
zu ändern. Dies würde bedeuten, dass der scheinbar harmlose (weil nur lesbare) Ruf zu empty
tatsächlich einen Konflikt verursachen kann. Leider können Sie nicht verlassen auf der Annahme, dass schreibgeschützte Aufrufe mit STL-Containern sicher sind.
In der Praxis aber, bin ich ziemlich sicher, dass vector::empty
wird nichtkeine Mitglieder ändern.Aber schon für list::empty
bin ich weniger sicher. Wenn Sie wirklich wollen Garantien, dann sperren Sie entweder alle Zugriff oder verwenden Sie nicht die STL-Container.
Danke für die Antworten. Um die Frage zu klären: Ein weiterer Thread wird zu den Elementen hinzugefügt. Kein anderer Thread wird von Elementen entfernt - Löschvorgänge werden nur innerhalb von DoStuffWithItems() ausgeführt und nur ein einzelner Thread ruft DoStuff() auf. Es ist in Ordnung, wenn items.empty() false zurückgibt, während ein anderer Thread es hinzufügt. Es ist nicht in Ordnung, wenn items.empty() dazu führt, dass die Anwendung abstürzt, wenn ein anderer Thread hinzugefügt wird –