Multithreading New/Delete



  • matti83 schrieb:

    wie kann ich das debuggen 😕

    Besser als Debuggen ist, auf Low-Level-Mechanismen wie manuelle Speicheranforderung weitgehend zu verzichten, um solche Fehler in Zukunft stark einzudämmen. Verwende Objekte, die Speicher verwalten (Stichwort RAII) und bei denen sich der Anwender nicht um Handlanger-Arbeiten kümmern muss.

    In deinem Fall würde ich aber versuchen, gleich mit einem Debugger an der Stelle zu schauen, wo der Fehler auftritt. Und auch nochmals selbst überlegen, ob der Code in diesem Kontext Sinn macht. Notfalls irgendein Speicher-Überwachungstool ausprobieren. Um was für einen Fehler handelt es sich überhaupt, in welcher Form zeigt er sich?



  • matti83 schrieb:

    also ich nutze unter linux die pthread library.

    und bekomme diesen fehler: "memory clobbered past end of allocated block"

    wenn ich die "delete-operatoren" überschreibe und nichts lösche, läuft das programm super 😉 - aber das ist ja nicht das Ziel.

    Dein Problem hat u.U. (vermutlich) mit Threads gar nix zu tun. Wäre höchstens möglich, wenn die Heap-Implementierung nicht mit Threads klarkommt. Sobald du PTHREADS verwendest, sollte allerdings sichergestellt sein, dass der Heap Thread-Safe ist.

    ps: Du musst natürlich sicherstellen, dass das Objekt, wenn du es löscht, in anderen Threads nicht mehr verwendet wird. Ebenso musst du Zugriffe auf das Objekt synchronisieren. Die üblichen Dinge halt wenn es um Multithreading geht - die allerdings mit new/delete nicht wirklich etwas zu tun haben.



  • Wenn du ein Objekt in einem Thread erzeugst und es dann an einen anderen Thread übergibst, damit dieser es benutzt oder löscht, dann musst du diesen Übergabeprozess irgendwie absichern, z.B. mit einer CriticialSection.

    Ich hab für derartige Threadkommunikation eine Queue gebaut, die die Übergabe für mich übernimmt. Ich schiebe das Objekt bloß dort rein und der andere Thread bekommt die Nachricht dann geliefert und kann damit tun was er will.

    Willst du jedoch das Objekt in einem Thread verwalten aber in mehreren Threads nutzen, musst du dir was anderes überlegen. Z.B. eine CriticalSection um jeden Zugriff drumherum ziehen, oder das Objekt sogar kopieren, damit jeder Thread sein eigenes Objekt hat. CriticalSections kosten mitunter Performance wenn ein Thread warten muss, weil ein anderer gerade in der CS drin ist.



  • Sind Critical Sections nicht Windoof-spezifisch? Ich würde hier etwas allgemeiner von Mutexes oder Wait conditions sprechen.



  • 314159265358979 schrieb:

    Sind Critical Sections nicht Windoof-spezifisch? Ich würde hier etwas allgemeiner von Mutexes oder Wait conditions sprechen.

    Ist egal. Andersbetriebsystemische haben das Wort auch zu verstehen.
    Außerdem heißt das Betriebssystem, das Du meinst "Windows".



  • @314
    Eine Critical-Section ist eine Mutex. Und was soll bitte eine "Wait-Condition" sein?



  • @hustbaer
    Das, wobei du mir in meinem IRC-Bot Thread geholfen hast. 😉



  • Unter einer Critical Section verstehe ich einen Codeabschnitt, dessen Ausführung nicht unterbrochen werden darf.



  • Und ein Mutex geht über den Prozess hinaus und lässt sich nicht mit einer Critical Section gleichsetzen.



  • jkljk schrieb:

    Und ein Mutex geht über den Prozess hinaus und lässt sich nicht mit einer Critical Section gleichsetzen.

    Wikipedia sagt das dazu:

    Mutual exclusion (often abbreviated to mutex) algorithms are used in concurrent programming to avoid the simultaneous use of a common resource, such as a global variable, by pieces of computer code called critical sections. A critical section is a piece of code in which a process or thread accesses a common resource. The critical section by itself is not a mechanism or algorithm for mutual exclusion. A program, process, or thread can have the critical section in it without any mechanism or algorithm which implements mutual exclusion.

    ?



  • Unter einer CriticalSection verstehe ich einen Bereich, der nur von einem Thread gleichzeitig betreten werden darf...



  • Unter einer Critical-Section versteht Windows eine "lokale" Mutex (=nicht prozessübergreifend).

    jkljk schrieb:

    Und ein Mutex geht über den Prozess hinaus und lässt sich nicht mit einer Critical Section gleichsetzen.

    Quatsch. Nur weil Windows die lokale Mutex CRITICAL_SECTION nennt, und die globale Mutex eben MUTEX, heisst das nicht dass eine Mutex immer global sein muss. Eine Mutex ist ein Ding das das Konzept "mutual exclusion" umsetzt. Ob lokal oder global ist komplett wurscht. -> Eine CRITICAL_SECTION ist eine Mutex.

    314159265358979 schrieb:

    @hustbaer
    Das, wobei du mir in meinem IRC-Bot Thread geholfen hast. 😉

    Meinst du eine Condition-Variable?



  • hustbaer schrieb:

    Meinst du eine Condition-Variable?

    Genau die. Das kenne ich als "Wait condition".



  • Das ist die Fehlermeldung: memory clobbered past end of allocated block

    Bedeutet das, dass ich meine Speicherbereiche überschreibe?
    Habe alle memmove-aufrufe mit 1000 if's gesichert... also längen geprüft. die sollten eig nichts überschreiben.



  • matti83 schrieb:

    Habe alle memmove-aufrufe mit 1000 if's gesichert... also längen geprüft.

    Dazu verwendet man normalerweise nicht if , sondern assert . Einerseits erfährst du so direkt von dem Fehler, andererseits verbrätst du im Release-Modus keine Rechenzeit mit der Überprüfung von Logikfehlern.

    Zu Low-Level-Funktionalität und ihrer Fehleranfälligkeit habe ich im Weiteren schon was gesagt. Wo genau brauchst du std::memmove() ?

    Ansonsten halt die übliche Taktik anwenden: Nach und nach Teile weglassen/auskommentieren, bis du den Fehler eingrenzen kannst.



  • matti83 schrieb:

    Das ist die Fehlermeldung: memory clobbered past end of allocated block

    Bedeutet das, dass ich meine Speicherbereiche überschreibe?

    Ja



  • Meldung von gdb auf ein print eines Objekts:

    warning: can't find linker symbol for virtual table for ByteBuffer' value warning: foundconstruction vtable for BaseObj-in-ByteBuffer' instead

    ByteBuffer ist von BaseObj abgeleitet.
    Die Meldung weißt auch darauf hin, dass ich meinen Speicher irgendwo zerschieße - ja?

    Wenn ich mir den Speicher zerschieße - wie kann es dann sein, dass das Prog einwandfrei läuft, wenn ich delete vollständig weg lasse? Zufall?



  • matti83 schrieb:

    Wenn ich mir den Speicher zerschieße - wie kann es dann sein, dass das Prog einwandfrei läuft, wenn ich delete vollständig weg lasse? Zufall?

    Wenn du das delet weglässt, hast du ein Speicherleck, das heißt, der Speicher wird einfach nicht mehr freigegeben. Dein Programm läuft dann problemlos durch, allerdings musst du hoffen, dass das Betriebssystem hinterher den verlorenen Speicher wieder freigibt.



  • Naja, es läuft auch nur so lange problemlos durch, wie noch genügend Speicher zur Verfügung steht (inkl. swap). Wenn das Programm mal Tage/Wochen läuft kann auch das in die Hose gehen.



  • Die Frage ist ja eigentlich auch: "Warum schmiert es weg, wenn das delete benutzt wird?"


Anmelden zum Antworten