Stringrückgabe in Threads aus einer DLL

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Stringrückgabe in Threads aus einer DLL

Beitrag 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
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag 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.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Warum gibste überhaupt einen String zurück?
Speicher allokieren mit SysAllocString_ oder auch mit AllocateMemory wäre
doch sinnvoller.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Re: Stringrückgabe in Threads aus einer DLL

Beitrag 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
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag 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
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag 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.
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag 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
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag 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
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten