Seite 1 von 2

Stringrückgabe in Threads aus einer DLL

Verfasst: 21.07.2009 22:05
von cxAlex
Ist nicht direkt ein Bug sondern eine Lücke im Stringmanager von PB:

Wenn ich normal nen String aus ner DLL zurückgebe muss der String global sein. Wenn die Funktion in Threads aufgerufen wird muss der String mit einer Mutex geschützt werden, da bei globalen String der TLS vom Thread-Safe Mode nicht greift. ABER: Die Mutex muss vor dem ProcedureReturn wieder freigegeben werden sonst kommt es zu einem Deathlock. Das heißt zwischen "UnlockMutex(Mutex) und "ProcedureReturn String" MUSS der String ungeschützt sein. Das heißt ich kann nicht garantieren das der Inhalt des String nicht von einem anderen Thread inzwischen überschrieben wurde?

Gruß, Alex

Verfasst: 21.07.2009 22:16
von ts-soft
Hab zwar von Threads und Mutex nicht viel Ahnung, aber warum muß der
String Global sein?
Static reicht doch auch. Ob das jetzt weiterhilft weiß ich aber nicht.

Verfasst: 21.07.2009 22:19
von cxAlex
Muss so sein weil PB - Stringmanager so will:
PB - Hilfe hat geschrieben:Hinweise zur Rückgabe von Strings aus DLL's:

Bei der Rückgabe von Strings aus einer DLL-Funktion muß der String als Global deklariert sein.

Ohne die Deklaration als Global ist der String nur Lokal in der ProcedureDLL verfügbar und kann somit nicht außerhalb verwendet werden
Static währ noch böser als Global, da hätt ich nicht nur nen Haufen ungeschütze Zugriffe sondern würd auch noch mit nen falschem Scope arbeiten... :twisted:

> Ob das jetzt weiterhilft weiß ich aber nicht.

Trozdem Danke.

Gruß, Alex

Leider nein, der Unlock-Return Zwischenraum währ immer noch da.

Verfasst: 21.07.2009 22:24
von ts-soft
Warum gibste überhaupt einen String zurück?
Speicher allokieren mit SysAllocString_ oder auch mit AllocateMemory wäre
doch sinnvoller.

Verfasst: 21.07.2009 22:29
von Kaeru Gaman
> Static währ noch böser als Global, da hätt ich nicht nur nen Haufen ungeschütze Zugriffe sondern würd auch noch mit nen falschem Scope arbeiten...

:?:

der string darf nicht "normal" sein, weil er dann nach beenden der Proc gelöscht wird.
wenn man ihn Static deklariert, bleibt er auch erhalten, und man könnte mit nem Pointer über ihn zugreifen.. denke ich.

Re: Stringrückgabe in Threads aus einer DLL

Verfasst: 21.07.2009 22:30
von helpy
cxAlex hat geschrieben:Ist nicht direkt ein Bug sondern eine Lücke im Stringmanager von PB
Nö! Sehe ich nicht als Lücke des StringManagers!
cxAlex hat geschrieben:... Das heißt zwischen "UnlockMutex(Mutex) und "ProcedureReturn String" MUSS der String ungeschützt sein. Das heißt ich kann nicht garantieren das der Inhalt des String nicht von einem anderen Thread inzwischen überschrieben wurde?
Wie wäre es mit einem eigens allokierten Speicher, der vom Hauptprogramm nach dem Auslesen wieder freigegeben wird. Dann brauchst Du keine globalen Variablen.

Eine andere Möglichkeit wäre ein globales String-Array einer festen Größe (verwendet als Ringspeicher) ... wo mit jedem Funktionsaufruf ein anderes Element zurückgegeben wird.

cu, guido

Verfasst: 21.07.2009 22:40
von cxAlex
> Speicher allokieren mit SysAllocString_ oder auch mit AllocateMemory wäre doch sinnvoller.

> Wie wäre es mit einem eigens allokierten Speicher, der vom Hauptprogramm nach dem Auslesen wieder freigegeben wird. Dann brauchst Du keine globalen Variablen.

Jo, so werd ichs sowieso machen müssen. Aber es geht mir darum das es hierfür keine native Lösung gibt, obwohl beides (Strings in Threads, Strings in DLLs) unterstützt wird.

Gruß, Alex

Verfasst: 22.07.2009 08:39
von helpy
cxAlex hat geschrieben:Jo, so werd ichs sowieso machen müssen. Aber es geht mir darum das es hierfür keine native Lösung gibt, obwohl beides (Strings in Threads, Strings in DLLs) unterstützt wird.
Haben aber beide nichts miteinander zu tun! Wenn in einem Thread auf einen globalen String zugegriffen wird, so muss dieser String vor dem Verarbeiten durch einen Mutex geschützt werden!

Wäre es nicht sinnvoller den Aufruf der DLL-Funktion und die Verarbeitung des zurückgegebenen Strings im Hauptprogramm per Mutex zu schützen als mit einem Mutex innerhalb der DLL-Funktion!

Zitat von freak http://www.purebasic.fr/english/viewtop ... 221#239221 :
Each thread has its own stack, so all local variables/procedure parameters will be different for each thread. Only static, shared and global will be shared between all thread. (and also between recursive calls in the same thread of course)
==> Deshalb müssen static, shared und global bei Verwendung in Threads immer geschützt werden.

Verfasst: 22.07.2009 17:10
von cxAlex
> Wenn in einem Thread auf einen globalen String zugegriffen wird, so muss dieser String vor dem Verarbeiten durch einen Mutex geschützt werden!

Hab ich doch die ganze Zeit geschrieben.

>Wäre es nicht sinnvoller den Aufruf der DLL-Funktion und die Verarbeitung des zurückgegebenen Strings im Hauptprogramm per Mutex zu schützen als mit einem Mutex innerhalb der DLL-Funktion!

Ich will überhaupt keine Mutex verwenden, dadurch kann die Funktion nur durch 1. Thread gleichzeitig genutzt werden und ich schaffe mir damit einen nicht geplanten Syncronisationspunkt und verliere Performance. Ich werd das ganze wohl anders lösen müssen.

Gruß, Alex

Verfasst: 22.07.2009 17:35
von PMV
Das du nach ProcedureReturn kein Mutex mehr freigeben kannst, ist
logisch. Würde das aber gehen, hättest du ein Problem: Das Aufrufende
Programm kann diesen String nun jeder Zeit abrufen, asyncron ohne Mutex.

Das ist so natürlich nicht erwünscht. Dir bleibt also nichts anderes, als mit
selber reserviertem Speicher zu arbeiten ... vorzugsweise Speicher, der
vom aufrufenden Programm reserviert wurdem, denn Speicher freigeben
von deiner DLL kann das Aufrufende Programm nicht. :wink:

MFG PMV