Skip to content

Instantly share code, notes, and snippets.

@aziascreations
Created November 7, 2020 11:10
Show Gist options
  • Save aziascreations/74a8dcac01708629a79811d2920a0d6f to your computer and use it in GitHub Desktop.
Save aziascreations/74a8dcac01708629a79811d2920a0d6f to your computer and use it in GitHub Desktop.
ThreadedWorkerTemplate.pb
;- Compiler directives & imports
EnableExplicit
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Required: Thread-safe compiler flag."
CompilerEndIf
;- Constants & Structures
#WorkerPool_Size = 128
#WorkerPool_PostBirthDelay = 5
Structure ThreadParameters
OutputListMutex.i
EndStructure
Global NewList OutputList.i()
;- Procedures
Procedure CustomWorkerThread(*Parameters.ThreadParameters)
Delay(Random(100, 10))
LockMutex(*Parameters\OutputListMutex)
AddElement(OutputList())
OutputList() = Random(255, 0)
UnlockMutex(*Parameters\OutputListMutex)
Delay(Random(100, 10))
EndProcedure
;- Code
NewList WorkerPoolThreadIDs.i()
NewList WorkerPoolThreadParams.i()
Define iWorkerPool.i
Define OutputMutex = CreateMutex()
Define *TmpThreadParams.ThreadParameters
; Initializing the worker lists...
For iWorkerPool = 0 To #WorkerPool_Size - 1
InsertElement(WorkerPoolThreadIDs())
WorkerPoolThreadIDs() = #Null
InsertElement(WorkerPoolThreadParams())
WorkerPoolThreadParams() = #Null
Next
iWorkerPool = 0
Define StartTimeTest.q = ElapsedMilliseconds()
; Spawning the threads...
While iWorkerPool < 100
ForEach WorkerPoolThreadIDs()
If Not IsThread(WorkerPoolThreadIDs())
; Cleaning up some garbage (leftovers from previous threads)
SelectElement(WorkerPoolThreadParams(), ListIndex(WorkerPoolThreadIDs()))
If WorkerPoolThreadParams()
FreeMemory(WorkerPoolThreadParams())
EndIf
WorkerPoolThreadParams() = AllocateMemory(SizeOf(ThreadParameters))
*TmpThreadParams = WorkerPoolThreadParams()
*TmpThreadParams\OutputListMutex = OutputMutex
WorkerPoolThreadIDs() = CreateThread(@CustomWorkerThread(), *TmpThreadParams)
; Staggers the launch of future threads (not required !)
CompilerIf #WorkerPool_PostBirthDelay <> 0
Delay(#WorkerPool_PostBirthDelay)
CompilerEndIf
iWorkerPool = iWorkerPool + 1
Break
EndIf
Next
Wend
; Waiting for the last threads to finish...
ForEach WorkerPoolThreadIDs()
If IsThread(WorkerPoolThreadIDs())
WaitThread(WorkerPoolThreadIDs())
EndIf
Next
Define EndTimeTest.q = ElapsedMilliseconds()
; Cleaning up...
ForEach WorkerPoolThreadParams()
If WorkerPoolThreadParams()
FreeMemory(WorkerPoolThreadParams())
EndIf
Next
Debug "Done !"
Debug "Took " + Str(EndTimeTest - StartTimeTest) + "ms"
Debug "Spawned "+Str(iWorkerPool)+" thread(s)"
Debug "Worker pool size: " + Str(#WorkerPool_Size)
Debug "Worker post-birth delay: " + Str(#WorkerPool_PostBirthDelay) + "ms"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment