Example of 8 user codes executed with 1, 2, 4, or 8 secondary threads:
Code: Select all
Type ThreadInitThenMultiStart
Public:
Declare Constructor()
Declare Sub ThreadInit(Byval pThread As Function(Byval As Any Ptr) As String, Byval p As Any Ptr = 0)
Declare Sub ThreadStart()
Declare Sub ThreadStart(Byval p As Any Ptr)
Declare Function ThreadWait() As String
Declare Property ThreadState() As Ubyte
Declare Destructor()
Private:
Dim As Function(Byval p As Any Ptr) As String _pThread
Dim As Any Ptr _p
Dim As Any Ptr _mutex1
Dim As Any Ptr _mutex2
Dim As Any Ptr _mutex3
Dim As Any Ptr _pt
Dim As Byte _end
Dim As String _returnF
Dim As Ubyte _state
Declare Static Sub _Thread(Byval p As Any Ptr)
End Type
Constructor ThreadInitThenMultiStart()
This._mutex1 = Mutexcreate()
Mutexlock(This._mutex1)
This._mutex2 = Mutexcreate()
Mutexlock(This._mutex2)
This._mutex3 = Mutexcreate()
Mutexlock(This._mutex3)
End Constructor
Sub ThreadInitThenMultiStart.ThreadInit(Byval pThread As Function(Byval As Any Ptr) As String, Byval p As Any Ptr = 0)
This._pThread = pThread
This._p = p
If This._pt = 0 Then
This._pt= Threadcreate(@ThreadInitThenMultiStart._Thread, @This)
Mutexunlock(This._mutex3)
This._state = 1
End If
End Sub
Sub ThreadInitThenMultiStart.ThreadStart()
Mutexlock(This._mutex3)
Mutexunlock(This._mutex1)
End Sub
Sub ThreadInitThenMultiStart.ThreadStart(Byval p As Any Ptr)
Mutexlock(This._mutex3)
This._p = p
Mutexunlock(This._mutex1)
End Sub
Function ThreadInitThenMultiStart.ThreadWait() As String
Mutexlock(This._mutex2)
Mutexunlock(This._mutex3)
This._state = 1
Return This._returnF
End Function
Property ThreadInitThenMultiStart.ThreadState() As Ubyte
Return This._state
End Property
Sub ThreadInitThenMultiStart._Thread(Byval p As Any Ptr)
Dim As ThreadInitThenMultiStart Ptr pThis = p
Do
Mutexlock(pThis->_mutex1)
If pThis->_end = 1 Then Exit Sub
pThis->_state = 2
pThis->_returnF = pThis->_pThread(pThis->_p)
pThis->_state = 4
Mutexunlock(pThis->_mutex2)
Loop
End Sub
Destructor ThreadInitThenMultiStart()
If This._pt > 0 Then
This._end = 1
Mutexunlock(This._mutex1)
.ThreadWait(This._pt)
End If
Mutexdestroy(This._mutex1)
Mutexdestroy(This._mutex2)
Mutexdestroy(This._mutex3)
End Destructor
'---------------------------------------------------
Type ThreadPooling
Public:
Declare Constructor()
Declare Sub PoolingSubmit(Byval pThread As Function(Byval As Any Ptr) As String, Byval p As Any Ptr = 0)
Declare Sub PoolingWait()
Declare Sub PoolingWait(values() As String)
Declare Property PoolingState() As Ubyte
Declare Destructor()
Private:
Dim As Function(Byval p As Any Ptr) As String _pThread0
Dim As Any Ptr _p0
Dim As Function(Byval p As Any Ptr) As String _pThread(Any)
Dim As Any Ptr _p(Any)
Dim As Any Ptr _mutex1
Dim As Any Ptr _mutex2
Dim As Any Ptr _pt
Dim As Byte _end
Dim As String _returnF(Any)
Dim As Ubyte _state
Declare Static Sub _Thread(Byval p As Any Ptr)
End Type
Constructor ThreadPooling()
Redim This._pThread(0)
Redim This._p(0)
Redim This._returnF(0)
This._mutex1 = Mutexcreate()
This._mutex2 = Mutexcreate()
Mutexlock(This._mutex2)
This._pt= Threadcreate(@ThreadPooling._Thread, @This)
End Constructor
Sub ThreadPooling.PoolingSubmit(Byval pThread As Function(Byval As Any Ptr) As String, Byval p As Any Ptr = 0)
Mutexlock(This._mutex1)
If Ubound(This._pThread) = 0 Then
Mutexunlock(This._mutex2)
End If
Redim Preserve This._pThread(Ubound(This._pThread) + 1)
This._pThread(Ubound(This._pThread)) = pThread
Redim Preserve This._p(Ubound(This._p) + 1)
This._p(Ubound(This._p)) = p
Mutexunlock(This._mutex1)
This._state = 1
End Sub
Sub ThreadPooling.PoolingWait()
This._end = 1
Mutexunlock(This._mutex2)
.ThreadWait(This._pt)
This._end = 0
Redim This._returnF(0)
This._state = 0
This._pt= Threadcreate(@ThreadPooling._Thread, @This)
End Sub
Sub ThreadPooling.PoolingWait(values() As String)
This._end = 1
Mutexunlock(This._mutex2)
.ThreadWait(This._pt)
This._end = 0
If Ubound(This._returnF) > 0 Then
Redim values(1 To Ubound(This._returnF))
For I As Integer = 1 To Ubound(This._returnF)
values(I) = This._returnF(I)
Next I
Redim This._returnF(0)
Else
Erase values
End If
This._state = 0
This._pt= Threadcreate(@ThreadPooling._Thread, @This)
End Sub
Property ThreadPooling.PoolingState() As Ubyte
Return This._state
End Property
Sub ThreadPooling._Thread(Byval p As Any Ptr)
Dim As ThreadPooling Ptr pThis = p
Do
Mutexlock(pThis->_mutex1)
While Ubound(pThis->_pThread) = 0
Mutexunlock(pThis->_mutex1)
pThis->_state = 4
Mutexlock(pThis->_mutex2)
If pThis->_end = 1 And Ubound(pThis->_pThread) = 0 Then Exit Sub
Mutexlock(pThis->_mutex1)
Wend
pThis->_pThread0 = pThis->_pThread(1)
pThis->_p0 = pThis->_p(1)
For I As Integer = 2 To Ubound(pThis->_pThread)
pThis->_pThread(I - 1) = pThis->_pThread(I)
pThis->_p(I - 1) = pThis->_p(I)
Next I
Redim Preserve pThis->_pThread(Ubound(pThis->_pThread) - 1)
Redim Preserve pThis->_p(Ubound(pThis->_p) - 1)
Mutexunlock(pThis->_mutex1)
Redim Preserve pThis->_ReturnF(Ubound(pThis->_returnF) + 1)
pThis->_state = 2
pThis->_returnF(Ubound(pThis->_returnF)) = pThis->_pThread0(pThis->_p0)
Loop
End Sub
Destructor ThreadPooling()
This._end = 1
Mutexunlock(This._mutex2)
.ThreadWait(This._pt)
Mutexdestroy(This._mutex1)
Mutexdestroy(This._mutex2)
End Destructor
'---------------------------------------------------
Function UserCode1 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "1";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode2 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "2";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode3 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "3";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode4 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "4";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode5 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "5";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode6 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "6";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode7 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "7";
Sleep 100, 1
Next I
Return ""
End Function
Function UserCode8 (Byval p As Any Ptr) As String
For I As Integer = 1 To 9
Print "8";
Sleep 100, 1
Next I
Return ""
End Function
'---------------------------------------------------
Dim As ThreadInitThenMultiStart ta1, ta2, ta3, ta4, ta5, ta6, ta7, ta8
Dim As ThreadPooling tb1, tb2, tb3, tb4, tb5, tb6, tb7, tb8
'---------------------------------------------------
Print "'ThreadInitThenMultiStart' with 1 secondary thread:"
Print " ";
ta1.ThreadInit(@UserCode1)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode2)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode3)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode4)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode5)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode6)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode7)
ta1.ThreadStart()
ta1.ThreadWait()
ta1.ThreadInit(@UserCode8)
ta1.ThreadStart()
ta1.ThreadWait()
Print
'---------------------------------------------------
Print "'ThreadPooling' with 1 secondary thread:"
Print " ";
tb1.PoolingSubmit(@UserCode1)
tb1.PoolingSubmit(@UserCode2)
tb1.PoolingSubmit(@UserCode3)
tb1.PoolingSubmit(@UserCode4)
tb1.PoolingSubmit(@UserCode5)
tb1.PoolingSubmit(@UserCode6)
tb1.PoolingSubmit(@UserCode7)
tb1.PoolingSubmit(@UserCode8)
tb1.PoolingWait()
Print
Print
'---------------------------------------------------
Print "'ThreadInitThenMultiStart' with 2 secondary threads:"
Print " ";
ta1.ThreadInit(@UserCode1)
ta2.ThreadInit(@UserCode2)
ta1.ThreadStart()
ta2.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
ta1.ThreadInit(@UserCode3)
ta2.ThreadInit(@UserCode4)
ta1.ThreadStart()
ta2.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
ta1.ThreadInit(@UserCode5)
ta2.ThreadInit(@UserCode6)
ta1.ThreadStart()
ta2.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
ta1.ThreadInit(@UserCode7)
ta2.ThreadInit(@UserCode8)
ta1.ThreadStart()
ta2.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
Print
'---------------------------------------------------
Print "'ThreadPooling' with 2 secondary threads:"
Print " ";
tb1.PoolingSubmit(@UserCode1)
tb2.PoolingSubmit(@UserCode2)
tb1.PoolingSubmit(@UserCode3)
tb2.PoolingSubmit(@UserCode4)
tb1.PoolingSubmit(@UserCode5)
tb2.PoolingSubmit(@UserCode6)
tb1.PoolingSubmit(@UserCode7)
tb2.PoolingSubmit(@UserCode8)
tb1.PoolingWait()
tb2.PoolingWait()
Print
Print
'---------------------------------------------------
Print "'ThreadInitThenMultiStart' with 4 secondary threads:"
Print " ";
ta1.ThreadInit(@UserCode1)
ta2.ThreadInit(@UserCode2)
ta3.ThreadInit(@UserCode3)
ta4.ThreadInit(@UserCode4)
ta1.ThreadStart()
ta2.ThreadStart()
ta3.ThreadStart()
ta4.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
ta3.ThreadWait()
ta4.ThreadWait()
ta1.ThreadInit(@UserCode5)
ta2.ThreadInit(@UserCode6)
ta3.ThreadInit(@UserCode7)
ta4.ThreadInit(@UserCode8)
ta1.ThreadStart()
ta2.ThreadStart()
ta3.ThreadStart()
ta4.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
ta3.ThreadWait()
ta4.ThreadWait()
Print
'---------------------------------------------------
Print "'ThreadPooling' with 4 secondary threads:"
Print " ";
tb1.PoolingSubmit(@UserCode1)
tb2.PoolingSubmit(@UserCode2)
tb3.PoolingSubmit(@UserCode3)
tb4.PoolingSubmit(@UserCode4)
tb1.PoolingSubmit(@UserCode5)
tb2.PoolingSubmit(@UserCode6)
tb3.PoolingSubmit(@UserCode7)
tb4.PoolingSubmit(@UserCode7)
tb1.PoolingWait()
tb2.PoolingWait()
tb3.PoolingWait()
tb4.PoolingWait()
Print
Print
'---------------------------------------------------
Print "'ThreadInitThenMultiStart' with 8 secondary threads:"
Print " ";
ta1.ThreadInit(@UserCode1)
ta2.ThreadInit(@UserCode2)
ta3.ThreadInit(@UserCode3)
ta4.ThreadInit(@UserCode4)
ta5.ThreadInit(@UserCode5)
ta6.ThreadInit(@UserCode6)
ta7.ThreadInit(@UserCode7)
ta8.ThreadInit(@UserCode8)
ta1.ThreadStart()
ta2.ThreadStart()
ta3.ThreadStart()
ta4.ThreadStart()
ta5.ThreadStart()
ta6.ThreadStart()
ta7.ThreadStart()
ta8.ThreadStart()
ta1.ThreadWait()
ta2.ThreadWait()
ta3.ThreadWait()
ta4.ThreadWait()
ta5.ThreadWait()
ta6.ThreadWait()
ta7.ThreadWait()
ta8.ThreadWait()
Print
'---------------------------------------------------
Print "'ThreadPooling' with 8 secondary threads:"
Print " ";
tb1.PoolingSubmit(@UserCode1)
tb2.PoolingSubmit(@UserCode2)
tb3.PoolingSubmit(@UserCode3)
tb4.PoolingSubmit(@UserCode4)
tb5.PoolingSubmit(@UserCode5)
tb6.PoolingSubmit(@UserCode6)
tb7.PoolingSubmit(@UserCode7)
tb8.PoolingSubmit(@UserCode8)
tb1.PoolingWait()
tb2.PoolingWait()
tb3.PoolingWait()
tb4.PoolingWait()
tb5.PoolingWait()
tb6.PoolingWait()
tb7.PoolingWait()
tb8.PoolingWait()
Print
Print
Sleep
'ThreadInitThenMultiStart' with 1 secondary thread:
111111111222222222333333333444444444555555555666666666777777777888888888
'ThreadPooling' with 1 secondary thread:
111111111222222222333333333444444444555555555666666666777777777888888888
'ThreadInitThenMultiStart' with 2 secondary threads:
121221211221122112343443343434343443565665565656655665787887787878877887
'ThreadPooling' with 2 secondary threads:
121212212121212121433434434334433434656565656565565665788787878778788787
'ThreadInitThenMultiStart' with 4 secondary threads:
123442313124421313244231134212434321567867588567675868577568856756788675
'ThreadPooling' with 4 secondary threads:
234141233124213423143412421341232314757665777657576757677675757665777756
'ThreadInitThenMultiStart' with 8 secondary threads:
124356786875342114235786678532411342578668725431145327861486275353267841
'ThreadPooling' with 8 secondary threads:
231456785768413223146785578641235324168787164235524631873718624554682173
Each user code takes about 1 second:
- on my PC, using 1 secondary thread, about 8 seconds in all,
- on my PC, using 2 secondary threads, about 4 seconds in all,
- on my PC, using 4 secondary threads, about 2 seconds in all,
- on my PC, using 8 secondary threads, about 1 second in all.