2008-12-23 11 views
5

Ich versuche immer noch, ein sehr hinterhältiges Speicherbeschädigungsproblem zu debuggen. Ich bin auf einen Abschnitt meines Codes gestoßen, der Speicher auf einem Thread zuweist und ihn auf einem anderen löscht.Speicherzuweisung und Freigabe über Threads hinweg

Ich habe ein vages Gefühl, dass das falsch ist, aber ich bin mir nicht sicher warum. Die Threads teilen sich den Prozessspeicher und der Zugriff auf diese Strukturen ist durch einen Mutex geschützt, also denke ich, dass alles funktionieren würde. Aber ist da eine Gefahr, die ich nicht sehe?

Antwort

5

wie @monjardin in einer anderen Antwort erwähnt, gibt es nichts falsch mit dem, was Sie zu tun versuchen.

Als zusätzlichen Gedanken haben Sie nicht erwähnt, auf welcher Plattform usw. Sie dieses Problem haben, aber wenn Multithreading neu für Sie und/oder diese Anwendung ist, an der Sie arbeiten, möchten Sie sicher sein, dass Standard-Support-Bibliotheken, die Sie verwenden, sind die Thread-sicheren Versionen der Bibliotheken. In vielen Umgebungen/Plattformen stehen dem Entwickler sowohl die Single-Thread- als auch die Multi-Threaded-Versionen der Support-Bibliotheken zur Verfügung. Wenn Sie Threads verwenden, aber gegen die Single-Thread-Version der Bibliotheken verlinken, könnten viele schlimme Dinge passieren. Zum Beispiel in einer einzigen Thread-Support-Bibliothek für malloc() und free() würde es keinen Mutex-Schutz für den Haufen (als eine Optimierung) haben. Die Multithread-Version der Bibliothek würde dem Heap-Manager einen Mutex-Schutz hinzufügen, um mehr als einen Thread zu unterstützen, der den Heap gleichzeitig manipuliert. (Dies ist nur ein Beispiel).

0

Die Gefahr besteht darin, dass Multi-Thread-Code schwerer zu schreiben ist. Wenn das Programm jedoch korrekt ist, sollte es kein Problem geben. Dies ist wahrscheinlich ein häufiges Vorkommen in producer/consumer Mustern, bei denen der produzierende Thread Speicher reserviert, der in einem synchronized queue platziert und von einem verbrauchenden Thread freigegeben wird.

0

Solange die Zuweisung und Freigabe des Speichers richtig geschützt sind und Sie auch sicherstellen, dass die Strukturen nur zugegriffen werden, während sie unter dem gleichen Mutex sind, kann ich nicht wirklich sehe dies ein Problem zu sein. Beachten Sie, dass dies für Lese- und Schreibzugriff gilt, nicht nur für den Schreibzugriff, da Sie sicherstellen müssen, dass die Struktur beim Lesen von Daten dort bleibt, wo sie sich befindet.

Gibt es eine Chance, dass irgendwo Code versucht, auf diese Datenstrukturen außerhalb des Mutex-Schutzes zuzugreifen? Oder schlimmer noch, könnte es eine Chance geben, dass einige dieser Strukturen Opfer von C++ Objectives werden (sagen wir, sie werden zerstört, weil sie über boost :: shared_ptrs referenziert werden und das letzte shared_ptr gerade das Gebäude verlassen hat?

Sind Sie 100% sicher, dass es Speicherbeschädigung ist? Ein anderer Fehler, der sehr ähnlich aussieht, ist, wenn ein Code eine Referenz enthält, die nicht gelesen werden sollte, und das referenzierte Objekt aufgrund der Speicherumleitung verschoben wird wie das Hinzufügen, dass kann ein weiteres Element auf einen Vektor auslösen (nur ein Beispiel zu nennen).

+0

Es gibt keine strengen Anforderungen für den Mutex-Schutz beim Zugriff auf das Objekt, solange nur ein Thread den Zeiger auf das Objekt gleichzeitig "besitzt". Zum Beispiel im Producer/Consumer-Modell, das in einer anderen Antwort erwähnt wird –

1

Nein, das ist in Ordnung, und ziemlich häufig vor allem mit Windows-Programmierung mit CreateThread, wo Sie die Argumente auf dem Heap zuordnen können, und übergeben Sie das Argument als void * Argument CreateThread. Und am einfachsten ist es, wenn der aufgerufene Thread seine Argumente löscht, wenn sie fertig sind. Wenn Sie jedoch Probleme mit der Speicherbeschädigung haben und Bedenken haben, dass ein Thread den Speicher löscht, den ein anderer erstellt hat, sollten Sie vielleicht überlegen, ob ein doppelter Löschvorgang stattfindet, ob die Übertragung des jeweiligen Kontexts jetzt für die Bereinigung verantwortlich ist Speicher ist nicht klar, vielleicht tun es sowohl rufende als auch gerufene Sektion?

1

Denken Sie daran, dass der Speichermanager selbst Thread-sicher sein muss, nicht nur Ihre Verwendung des Speichers. Überprüfen Sie Ihre Plattformdokumente.

Verwandte Themen