[PB4 B10] CreateThread aber Thread noch nicht starten?

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Du hast aber auch Wünsche ;)

Code: Alles auswählen

CompilerIf #PB_Compiler_Thread

Procedure CreateThread_M(proc.l,value,flags.b)
  Protected result, pbproc, old
  
  
  !MOV Eax, _PB_CreateThread_THREAD@8
  !CMP byte[Eax+0x27], 0x6A
  !JNE asm_CreateThread_M_fail
  !CMP dword[Eax+0xAC], 0x0008C2C9
  !JNE asm_CreateThread_M_fail
  !MOV dword[p.v_pbproc], Eax
  
  
  If VirtualProtect_(pbproc,$100,#PAGE_EXECUTE_READWRITE,@old)
  
    PokeB(pbproc+$28,flags)
    result = CreateThread(proc,value)
    PokeB(pbproc+$28,$00)
    VirtualProtect_(pbproc,$100,old,@old)

    ProcedureReturn result
  EndIf
    
  !asm_CreateThread_M_fail:
  ProcedureReturn #False
EndProcedure

CompilerElse

Procedure CreateThread_M(proc.l,value,flags.b)
  Protected result, pbproc, old
  
  
  !MOV Eax, _PB_CreateThread@8
  !CMP byte[Eax+0x0B], 0x6A
  !JNE asm_CreateThread_M_fail
  !CMP dword[Eax+0x90], 0x0008C2C9
  !JNE asm_CreateThread_M_fail
  !MOV dword[p.v_pbproc], Eax
  
  If VirtualProtect_(pbproc,$100,#PAGE_EXECUTE_READWRITE,@old)
  
    PokeB(pbproc+$0C,flags)
    result = CreateThread(proc,value)
    PokeB(pbproc+$0C,$00)
    VirtualProtect_(pbproc,$100,old,@old)

    ProcedureReturn result
  EndIf
    
  !asm_CreateThread_M_fail:
  ProcedureReturn #False
EndProcedure

CompilerEndIf


;-Bsp

Procedure a(void)
  Debug 1234
  ProcedureReturn
EndProcedure

thread = CreateThread_M(@a(),0,#CREATE_SUSPENDED) ;Warten bis ResumeThread
Delay(500)
ResumeThread(thread)
Delay(500)
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Obwohl, man könnte Fred einfach fragen ob er schnell noch einen
optionalen Parameter hinzufügt :D ... Danke :allright:
Bild
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hi.
Wegen Ferien meiner Kinder war ich mal ne Weile nicht hier.

Ich mache das ganz einfach ohne ASM.
Man muß dazu am Anfang nur ne Schleife mit Wartebedingung einbauen, einer Globalen Variable halt (oder Liste).

repeat
delay(10)
until wartevar=1

ohne Globale Variablen geht es auch, dann mu8 man einfach als Parameter an den Thread den Pointer auf einen Long angeben. in diesen kann man dann wiederum den Pointer der lokalten Wartevariablen Schreiben und so diese einfach beschreiben. Fertig.
Das Funktioniert dann auch problemlos mit einer Unbegrenzten anzahl an Threads ohne viele Variablen dauerhaft zu belegen.

Grüßle
Thorsten
1. Win10
PB6.1
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

So weit ist es nu gekommen, jetzt muss ich mich schon selbst zitieren :?
MVXA hat geschrieben:Weil ich für sowas nicht einen Namen verschweden möchte, wenn man
das auch anders lösen könnte Wink.
Bild
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Ich konnte ja nicht wissen, das du was gegen unsere Nachbarn aus "Schweden" hast. *grins*

Aber was meinst du genau mit "Namen verschwe(n)den"? Man braucht dafür ja keine globale Variable wie ich meinte. es geht doch auch mit lokalen.
Aber du wirst ja wohl vielleicht die ASM-Variante nutzen. Die ist natürlich wenn sie geht klasse, "mir" nur wieder zu angepaßt an die PB-Version.

@Konne
Mit Pause Thread geht das leider nicht wirklich(sicher). Es kann gut passieren, da der Thread bereits arbeitet bevor im Hauptprogramm der Pausebefehl auftritt. So können schon einige Zeilen abgearbeitet sein (passierte bei mir manchmal).
Einzige supertolle Möglichkeite wäre:

Procedure DeineProzedur(Wert)
PauseThread(GetCurrentThreadID_())
; Die Variable 'Wert' wird 23 enthalten
EndProcedure

Leider geht das nicht, das PauseThread nicht das Systemhandle nutzt, sondern wohl eine pb-interne ID.

Toshy
1. Win10
PB6.1
Benutzeravatar
Eric
Beiträge: 303
Registriert: 05.09.2004 09:50
Wohnort: Göttingen

Beitrag von Eric »

Toshy hat geschrieben: Procedure DeineProzedur(Wert)
PauseThread(GetCurrentThreadID_())
; Die Variable 'Wert' wird 23 enthalten
EndProcedure

Leider geht das nicht, das PauseThread nicht das Systemhandle nutzt, sondern wohl eine pb-interne ID.
Toshy
Wenn schon WinAPI, warum dann nicht gleich

Code: Alles auswählen

SuspendThread_(GetCurrentThreadID_())
(Vielleicht pfuscht das aber auch der PB-Threadverwaltung dazwischen)
El_Choni_work: cant't you just spit the binary data to sqlite, as you would spit a hamster into a microwave oven?
* Fangles falls off the chair laughing
Bild
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Könnte gehen (mit dem gleichen Vorbehalt wie Eric, scheint aber zu gehen):

Code: Alles auswählen

Procedure thread(a.l)
  SuspendThread_(GetCurrentThread_())
  MessageRequester("Thread:", Str(a))
EndProcedure


Procedure.l CreateThreadEx(*proc, Value.l, susp.l)
  Protected ret.l, t.l
  If susp
    ret = CreateThread(*proc, Value)
    t = SuspendThread_(ret)
    While t = 0 Or t = -1
      If t = 0 : ResumeThread_(ret) : EndIf
      t = SuspendThread_(ret)
    Wend
    ResumeThread_(ret)
    ProcedureReturn ret
  Else
    ret = CreateThread(*proc, Value)
    Repeat
      Delay(0)
    Until ResumeThread_(ret) = 1
    
    ProcedureReturn ret
  EndIf
EndProcedure

ResumeThread(CreateThreadEx(@thread(), 21, 1))

Delay(1000)
MessageRequester("Program", "finished")
Und jetzt kürzt den Code mal, bin sicher da lässt sich noch was machen..
Bin leider schon völlig verwirrt und kanns nicht mehr vereinfachen.
Gesperrt