Autor Beitrag
Hami04
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 14.10.09 13:42 
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:
ausblenden 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
Hami04 Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Do 15.10.09 13:06 
Ich abe das Problem selbst gelöst bekommen.

Das Problem war, dass der Speichermanager der DLL nicht wusste, das mehrere Threads auf die DLL zugreifen. Der Speichermanager hat die Speicherzugriffe demzufolge nicht gesperrt. In Delphi gibt es eine Variable IsMultiThread. Diese Variable muss auf True gesetzt werden, dann sperrt der Speichermanager die Zugriffe, auch wenn in der DLL nur ein Thread gestartet ist.

forum.delphi-treff.d...owthread.php?t=13476

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 15.10.09 15:17 
Interessant.

Also sollte man das IsMultiThreaded dann direkt im DLLEntryPoint setzen? Oder an anderer Stelle?

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."