Stringrückgabe in Threads aus einer DLL
Stringrückgabe in Threads aus einer DLL
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
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

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
- 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
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.
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.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Muss so sein weil PB - Stringmanager so will:

> Ob das jetzt weiterhilft weiß ich aber nicht.
Trozdem Danke.
Gruß, Alex
Leider nein, der Unlock-Return Zwischenraum währ immer noch da.
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...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
> 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

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
- 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
Warum gibste überhaupt einen String zurück?
Speicher allokieren mit SysAllocString_ oder auch mit AllocateMemory wäre
doch sinnvoller.
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.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

-
Kaeru Gaman
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
> 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 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.
Der Weise weiß, dass er ein Narr ist.
Re: Stringrückgabe in Threads aus einer DLL
Nö! Sehe ich nicht als Lücke des StringManagers!cxAlex hat geschrieben:Ist nicht direkt ein Bug sondern eine Lücke im Stringmanager von PB
Wie wäre es mit einem eigens allokierten Speicher, der vom Hauptprogramm nach dem Auslesen wieder freigegeben wird. Dann brauchst Du keine globalen Variablen.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?
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)
PB Last Final / (Sometimes testing Beta versions)
> 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
> 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

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
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!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.
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 :
==> Deshalb müssen static, shared und global bei Verwendung in Threads immer geschützt werden.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)
Windows 10
PB Last Final / (Sometimes testing Beta versions)
PB Last Final / (Sometimes testing Beta versions)
> 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
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

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
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.
MFG PMV
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.
MFG PMV