Liebes Forum,
ich habe für mich unerklärliche Probleme beim Allozieren von Speicher in DLLs, wenn diese von verschiedenen Threads aufgerufen werden.
Ich habe das Problem schon ziemlich stark eingrenzen können.
Ich habe eine Prozedur, die 1 MB Speicher alloziert und diesen sofort wieder freigibt, wie diese hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure waste; cdecl; var p: Pointer; begin GetMem(p, 1024 * 1024); FreeMem(p); end; |
Ich habe verschiedene Szenarien probiert diese DLL aufzurufen:
1. Ein Thread ruft die Funktion in einem Unit des Hauptprogramms auf. → OK
2. Mehrere Threads (3) rufen die Funktion gleichzeitig in einem Unit des Hauptprogramms: → OK
3. Ein Thread ruft die Funktion aus einer DLL heraus aus: → OK
4. Mehre Threads rufen die Funktion aus einer DLL heraus aus: → Fehler unterschiedlichster Art (Invalid Pointer, Out Of Memory)
5. Mehrere Threads rufen die Funktion aus einer DLL heraus aus. Allerdings ist die Funktion über eine TCriticalSection geschützt (was eigentlich wieder zu einem Thread führt): → OK
6. Mehrere Threads rufen die Funktion aus einer DLL heraus aus. Allerdings benutzen Hauptprogramm und DLL ShareMem, also die borlndmm.dll und benutzen den Borland-Speicher-Manager. → OK
Das Problem tritt also nur auf, wenn mehrere Threads gleichzeitig in einer DLL Speicher allozieren.
Der Lösungsversuch in 6. ist nicht befriedigend, da die DLL sonst nur von Delphi-Programmen genutzt werden kann. Lösungsversuch 5. ist eigentlich in Ordnung, allerdings ist er sehr fehlerträchtig. Jedesmal wenn ein Objekt in einer DLL erzeugt wird müsste dieser Abschnitt geschützt werden, damit nicht irgendwann dumme Fehler passieren.
Das ganze scheint ein Problem der Windows-Speicher-Allokation zu sein. Man kann das Verhalten von Delphi zur Speicher-Allokation ja auch umstellen, allerdings sind mir die verschiedenen Konfigurationen nicht so ganz klar.
Hat schon einmal jemand ähnliche Erfahrungen gemacht, oder kann so etwas beitragen, oder hat jemand gar eine Lösung für das Problem?
Besten Dank im Vorraus