Zuerst ist TStringList
nicht Thread-sicher.
Zweitens wäre der Versuch, es so zu machen, eine schreckliche Idee für einen Low-Level-Container, der in den allermeisten Fällen nicht über mehrere Threads hinweg geteilt wird.
Drittens ist der naive Code, den Sie vorschlagen, um ihn threadsicher zu machen, völlig unzureichend. Es ist noch lange nicht wirklich threadsicher - was ein Teil des Problems ist, dies generisch zu versuchen.
Im Text Ihrer Frage, die Sie fragen:
Ist es ok, Daten von TStringList ohne jegliche Form der Synchronisation zu lesen?
Ja, es ist in Ordnung. In der Tat ist das bevorzugt, weil es effizienter ist.
jedoch, wenn die Daten über Threads gemeinsam genutzt wird, können Sie auf Probleme stoßen. Aus diesem Grund sollten Sie die Menge an Daten (nicht nur String-Listen) minimieren, die über Threads verteilt werden. Und wenn Sie müssen, um Daten zu teilen, tun Sie dies in einer geeigneten kontrollierten Weise.
auf Punkt Expanding 3
Der Grund Code ist nicht thread-sicher ist, dass es den Schutz alle Ihre Daten aus den gemeinsamen Zugriff bleibt.Dies ist ein weit verbreitetes Missverständnis in Multi-Threaded-Entwicklung: „Ich brauche nur bestimmte Operationen mit Schlössern wickeln, und alles wird in Ordnung sein.“
Der Punkt ist, wenn Ihre Liste gemeinsam genutzt wird, befinden Sie sich:
- Die Strukturen teilen, die den Container darstellen.
- AND Sie teilen die Datenmitglieder (die tatsächlichen Zeichenfolgen) selbst.
- Wenn Sie mit Strings arbeiten, geht das einen Schritt weiter, weil die Art, wie Delphi Strings verwaltet, sie durch interne Referenzzählung mit anderen Strings desselben Werts in einem ganz anderen Bereich der Anwendung teilen kann.
Während es möglich ist, Ihre Strategie vorgeschlagen Sperren könnte für Ihre aktuellen Anforderungen geeignet sein, es ist bei weitem nicht allgemein ist Thread-sicher.
Fazit
Wenn Sie Thread-sicher Code der Pflicht schreiben wollen, ist auf Sie zu:
- die Datenzugriffspfade verstehen.
- Minimieren Sie die Freigabe zwischen Threads (bei weitem der beste Knall für Bock).
- Und um die beste Strategie zu implementieren, um die Daten sicher zu teilen (von denen es viele Optionen gibt, und die Verriegelung ist nicht garantiert in jedem Fall die beste).
Nebenbei bemerkt
ich früher angedeutet, dass Ihre Sicherungstechnik nur „könnte für Ihre aktuellen Anforderungen geeignet sein“, weil ich Sie nicht glauben, haben wirklich einen Hinweis, wie Sie sie Echt Anforderungen. Wenn Sie dann Sie wirklich brauchen, Kenntnis von den folgenden zu nehmen:
Im Code, den Sie dort vorgestellt haben bei der Herstellung Ihrer TStringList
„thread-safe“ absolut keinen Nutzen wäre. Sie füllen die Liste in einer Schleife auf, und Sie lesen Werte in einer zweiten Schleife. Sie tun absolut nichts, um die Daten gleichzeitig zu verwenden.
Der Code, der Ihrem Multithreading am nächsten kommt, lautet: Es wäre eine gute Idee, beide Schleifen vom Hauptthread zu verarbeiten, um die UI nicht zu blockieren. In diesem Fall sollte der Hintergrundthread NICHT seine TStringList
Instanz teilen. Und kann einfach mit dem Hauptthread synchronisieren, um das Ergebnis (und möglicherweise Fortschrittsupdates) zu melden.
von nicht teilen Daten, die nicht der Fall ist brauchen geteilt werden, können Sie die Notwendigkeit für Schlösser vollständig umgehen. Sie wären ein unnötig Overhead.Und Sie können glücklich sein, dass TStringList
nicht einen eingebauten "Thread-Sicherheit" Mechanismus haben.
Sie müssen immer Speicher schützen, der gleichzeitig geschrieben und gelesen werden kann. In Ihrem Fall kann der Haupt-Thread lesen und der sekundäre Thread kann schreiben, also müssen Sie ja synchronisieren. – whosrdaddy
Wie könnte es möglicherweise sein? Der Compiler müsste deine Gedanken lesen. Fügen Sie eine Synchronisierung hinzu. –