Thread mit String Parameter

Anfängerfragen zum Programmieren mit PureBasic.
Marie23
Beiträge: 49
Registriert: 31.05.2008 18:14

Thread mit String Parameter

Beitrag von Marie23 »

Hallo, ist es möglich einen Thread mit String Parameter zu realisieren?

z.b.:

CreateThread(@MyThread(),MyStr.s)

funktioniert bei mir nicht


danke
Benutzeravatar
dige
Beiträge: 1236
Registriert: 08.09.2004 08:53

Beitrag von dige »

Du kannst einen Zeiger auf einen String übergeben und den Text mit
PeekS() auslesen:

Code: Alles auswählen

Procedure ThreadExample ( *Pointer )
  Debug PeekS(*Pointer)
EndProcedure

Strings.s = "Marie23"
CreateThread(@ThreadExample(), @Strings )
Delay(5000)
End
"Papa, ich laufe schneller - dann ist es nicht so weit."
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 »

Es muß aber auch sichergestellt werden, das der String sich ncht ändert,
weil sonst wird der Zeiger auch ungültig.

Auf jedenfall ist das der sicherste Weg zum Crash, man übergibt keine
Strings (pointer zum string) an nem Thread!
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
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> man übergibt keine Strings (pointer zum string) an nem Thread
Darf man denn wenigstens einem allokierten Speicherbereich übergeben?

Code: Alles auswählen

*p=AllocateMemory(1024)
PokeS(*p, "Hallo Welt")
CreateThread(@myProc(), *p)
Die weitere Verwaltung des Speicherbeichs könnte man den Thread zumuten, d. h. der Thread gibt den Speicher ggf. wieder frei, sodass der Hauptthread nichts mehr damit zu tun hat.

Das wäre doch möglich, oder?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Andreas_S
Beiträge: 787
Registriert: 14.04.2007 16:48
Wohnort: Wien Umgebung
Kontaktdaten:

Beitrag von Andreas_S »

Kopieren wäre besser, da du normalerweise den Speicher auf den der Parameter zeigt nicht werändern sollst...
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Andreas_S hat geschrieben:Kopieren wäre besser, da du normalerweise den Speicher auf den der Parameter zeigt nicht werändern sollst...
Wieso denn das?
Mit dem Speicher kann man machen was man will, bzw. mit dem Parameter. Das muss ja auch nicht zwingend ein Pointer sein.

So wie dige es macht, gibt es keine Probleme, wenn der String nicht mehr vom threaderstellenden Thread manipuliert wird.

Edit:
Man kann auch eine Structure übergeben, ist zwar etwas aufwendiger zu schreiben, sollte aber die schnellste und sicherste Möglichkeit sein.

Code: Alles auswählen

EnableExplicit

Structure StringStruct
  String.s
EndStructure


Procedure MyThread(*String.StringStruct)

  MessageRequester("",*String\String)

  End

EndProcedure

Define.StringStruct String

String\String = "Test"

CreateThread(@MyThread(),String)

Repeat
  Delay(100)
ForEver
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Thorium hat geschrieben: So wie dige es macht, gibt es keine Probleme, wenn der String nicht mehr vom threaderstellenden Thread manipuliert wird.
Nur ist das manchmal gar nicht ersichtlich was mit dem Speicher passiert.
Rufst du z.b. aus einer Procedure einen Thread auf und uebergibst einen
lokalen String, kann es ja unter Umstaenden sein, das die aufrufende
Funktion schon beendet wurde (und somit auch der Speicher des Strings
freigegeben) und es im Thread dann irgendwann kracht.

Code: Alles auswählen

Procedure a(*string)
	
	;Delay(1000)
	
	Debug PeekS(*string)
	
EndProcedure

Procedure b()
	
	Protected s.s = "teststring"
	
	CreateThread(@a(),@s)
	
EndProcedure

b()
Delay(10000)

Eine Kopie ist in diesem Fall erforderlich.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

kann ich daraus den Schluß ziehen, dass es am sichersten wäre,
Strings, die von Threads I/O benutzt werden sollen, global anzulegen?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

"Sicherer" ist es bestimmt, vertrauen wuerde ich darauf aber nicht,
da wir nicht wirklich wissen wie PB unter der Haube laeuft.
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Wenn der Pointer auf einen String übergeben wird (mit welcher Methode auch immer), muss in jedem Fall vom Programmierer sicher gestellt werden, dass der String nicht verändert wird, solange dieser nicht endgültig vom Thread (oder von was auch immer ;-)) verarbeitet worden ist.

Ich habe da vor kurzem etwas ähnliches, wie den folgenden Code verwendet:

Code: Alles auswählen

Procedure NewTmpString(s.s)
	Protected *s.String = AllocateMemory(StringByteLength(s)+SizeOf(Character))
	If *s
		PokeS(*s,s)
	EndIf
	ProcedureReturn *s
EndProcedure

Procedure.s GetTmpString(*s.String)
	Protected s.s
	If *s
		s = PeekS(*s)
		FreeMemory(*s)
	EndIf
	ProcedureReturn s
EndProcedure
Das ist nur eine Möglichkeit!

cu, guido
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Antworten