I have times a simple example created without special imported functions.
Maybe hate anyone more simple examples for beginners.
Update v1.03
- Update example with Semaphore
Code: Select all
;-TOP
; Comment: Simple Thread Control
; Author: mk-soft
; Version: v1.03
; Create: 22.11.2015
; Update: 01.09.2016
Enumeration
#thread_cmd_nothing
#thread_cmd_start
#thread_cmd_pause
#thread_cmd_continue
#thread_cmd_stop
EndEnumeration
Enumeration
#thread_state_nothing
#thread_state_startingup
#thread_state_running
#thread_state_pausing
#thread_state_paused
#thread_state_continued
#thread_state_stopping
#thread_state_stopped
#thread_state_finished
EndEnumeration
Enumeration #PB_Event_FirstCustomValue
#thread_event_state
EndEnumeration
Structure udtMyThread
; Header
id.i
signal.i
cmd.i
state.i
; Userdata
counter.i
EndStructure
; ***************************************************************************************
Procedure ThreadState()
Protected *this.udtMyThread
*this = EventGadget()
Select EventType()
Case #thread_state_nothing
StatusBarText(0, 0, "Nothing")
Case #thread_state_startingup
StatusBarText(0, 0, "Startingup")
Case #thread_state_running
StatusBarText(0, 0, "Running")
Case #thread_state_pausing
StatusBarText(0, 0, "Pause pending")
Case #thread_state_paused
StatusBarText(0, 0, "Paused")
Case #thread_state_continued
StatusBarText(0, 0, "Continued")
Case #thread_state_stopping
StatusBarText(0, 0, "Stopping")
Case #thread_state_stopped
StatusBarText(0, 0, "Stopped")
Case #thread_state_finished
StatusBarText(0, 0, "Finished")
EndSelect
EndProcedure
Macro SendThreadState(This, State)
PostEvent(#thread_event_state, 0, This, State)
EndMacro
; ***************************************************************************************
; Thread control macros
Macro MyStartThread(thread)
If Not IsThread(thread\id)
thread\id = CreateThread(@MyThread(), @thread1)
EndIf
thread\cmd = #thread_cmd_start
If thread\signal
SignalSemaphore(thread\signal)
EndIf
EndMacro
Macro MyPauseThread(thread)
thread\cmd = #thread_cmd_pause
EndMacro
Macro MyContinueThread(thread)
thread\cmd = #thread_cmd_continue
If thread\signal
SignalSemaphore(thread\signal)
EndIf
EndMacro
Macro MyStopThread(thread)
thread\cmd = #thread_cmd_stop
If thread\signal
SignalSemaphore(thread\signal)
EndIf
EndMacro
; ***************************************************************************************
Procedure MyThread(*this.udtMyThread)
Debug "Created Thread"
With *this
\signal = CreateSemaphore(1)
Repeat
Select \cmd
Case #thread_cmd_start
\cmd = #thread_cmd_nothing
If \state <= #thread_state_nothing Or \state >= #thread_state_finished
\state = #thread_state_startingup
SendThreadState(*this, \state)
;TODO Init thread
Debug "Init Thread"
Delay(2000)
\state = #thread_state_running
SendThreadState(*this, \state)
EndIf
Case #thread_cmd_pause
\cmd = #thread_cmd_nothing
If \state = #thread_state_running
\state = #thread_state_pausing
SendThreadState(*this, \state)
;TODO Pausing thread
Debug "Paused Thread"
Delay(2000)
\state = #thread_state_paused
SendThreadState(*this, \state)
EndIf
Case #thread_cmd_continue
\cmd = #thread_cmd_nothing
If \state = #thread_state_paused
\state = #thread_state_continued
SendThreadState(*this, \state)
;TODO Continue thread
Debug "Continue Thread"
Delay(2000)
\state = #thread_state_running
SendThreadState(*this, \state)
EndIf
Case #thread_cmd_stop
\cmd = #thread_cmd_nothing
If \state < #thread_state_stopping
\state = #thread_state_stopping
SendThreadState(*this, \state)
;TODO Stopping thread
Debug "Stopping Thread"
Delay(2000)
\state = #thread_state_stopped
SendThreadState(*this, \state)
EndIf
EndSelect
Select \state
Case #thread_state_running
;TODO Cycle programm
Debug "Thread running " + \counter
\counter + 1
Delay(1000)
Case #thread_state_nothing, #thread_state_paused
WaitSemaphore(\signal)
Default
Delay(100)
EndSelect
Until \state = #thread_state_stopped
Debug "Release Thread"
\state = #thread_state_finished
SendThreadState(*this, \state)
; Release thread
FreeSemaphore(\signal)
\signal = 0
\id = 0
EndWith
EndProcedure
; ***************************************************************************************
CompilerIf #PB_Compiler_IsMainFile
Global thread1.udtMyThread
Procedure Main()
If OpenWindow(0, #PB_Any, #PB_Any, 530, 60, "Simple Thread Control")
CreateStatusBar(0, WindowID(0))
AddStatusBarField(1000)
ButtonGadget(0, 10, 10, 120, 25, "Start")
ButtonGadget(1, 140, 10, 120, 25, "Pause")
ButtonGadget(2, 270, 10, 120, 25, "Continue")
ButtonGadget(3, 400, 10, 120, 25, "Stop")
BindEvent(#thread_event_state, @ThreadState())
; We can create thread without start processing
thread1\id = CreateThread(@MyThread(), @thread1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 0
MyStartThread(thread1)
Case 1
MyPauseThread(thread1)
Case 2
MyContinueThread(thread1)
Case 3
MyStopThread(thread1)
EndSelect
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
EndIf
EndProcedure : Main()
CompilerEndIf