Seite 2 von 2

Verfasst: 16.04.2006 02:15
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)

Verfasst: 16.04.2006 02:39
von MVXA
Obwohl, man könnte Fred einfach fragen ob er schnell noch einen
optionalen Parameter hinzufügt :D ... Danke :allright:

Verfasst: 17.04.2006 23:22
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

Verfasst: 18.04.2006 01:56
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.

Verfasst: 19.04.2006 17:59
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

Verfasst: 19.04.2006 18:24
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)

Verfasst: 19.04.2006 18:37
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.