ThreadCreate
Starts a user-defined procedure in a separate execution thread
Syntax
`
Declare Function ThreadCreate ( ByVal proc As Sub ( ByVal As Any Ptr ), ByVal param As Any Ptr = 0, ByVal stack_size As Integer = 0 ) As Any Ptr
`
Usage
`
result = ThreadCreate ( proc [, [ param ] [, stack_size ] ] )
`
Parameters
`proc`
A pointer to the `Sub` intended to work as a thread.
`param`
Optional Any Ptr argument for the `Sub` pointed to by `proc` (it can be a pointer to a structure or an array if more arguments are needed).
`stack_size`
Optional number of bytes to reserve for this thread's stack.
Return Value
Threadcreate returns an `Any Ptr` handle to the thread created, or the null pointer (`0`) on failure.
Description
The user function is started as a thread executes in parallel with the main part of the program. The OS achieves this by assigning it to a different processor if it exists, or using the waiting times in the main program.
Before closing, a program must wait for the termination of all the threads it has launched; see `ThreadWait`.
To avoid simultaneous access to shared resources from different threads, FreeBASIC implements mutexes, mutual exclusion locks that can be "owned" by a single thread when doing critical work. See `MutexCreate`, `MutexLock`, `MutexUnlock`, `MutexDestroy`.
On some systems, the stack automatically grows beyond `stack_size` if more space is needed; on others, this is the fixed maximum allowed. Behavior is undefined when more stack is used than the reserved size on systems where stacks are not able to grow.
Example
`
'' Threading synchronization using Mutexes
'' If you comment out the lines containing "MutexLock" and "MutexUnlock",
'' the threads will not be in sync and some of the data may be printed
'' out of place.
Const MAX_THREADS = 10
Dim Shared As Any Ptr ttylock
'' Teletype unfurls some text across the screen at a given location
Sub teletype( ByRef text As String, ByVal x As Integer, ByVal y As Integer )
''
'' This MutexLock makes simultaneously running threads wait for each
'' other, so only one at a time can continue and print output.
'' Otherwise, their Locates would interfere, since there is only one
'' cursor.
''
'' It's impossible to predict the order in which threads will arrive
'' here and which one will be the first to acquire the lock thus
'' causing the rest to wait.
''
MutexLock ttylock
For i As Integer = 0 To (Len(text) - 1)
Locate x, y + i
Print Chr(text[i])
Sleep 25
Next
'' MutexUnlock releases the lock and lets other threads acquire it.
MutexUnlock ttylock
End Sub
Sub thread( ByVal userdata As Any Ptr )
Dim As Integer id = CInt(userdata)
teletype "Thread (" & id & ").........", 1 + id, 1
End Sub
'' Create a mutex to syncronize the threads
ttylock = MutexCreate()
'' Create child threads
Dim As Any Ptr handles(0 To MAX_THREADS-1)
For i As Integer = 0 To MAX_THREADS-1
handles(i) = ThreadCreate(@thread, CPtr(Any Ptr, i))
If handles(i) = 0 Then
Print "Error creating thread:"; i
Exit For
End If
Next
'' This is the main thread. Now wait until all child threads have finished.
For i As Integer = 0 To MAX_THREADS-1
If handles(i) <> 0 Then
ThreadWait(handles(i))
End If
Next
'' Clean up when finished
MutexDestroy(ttylock)
`
`
Sub print_dots(ByRef char As String)
For i As Integer = 0 To 29
Print char;
Sleep CInt(Rnd() * 100), 1
Next
End Sub
Sub mythread(param As Any Ptr)
'' Work (other thread)
print_dots("*")
End Sub
Randomize(Timer())
Print " main thread: ."
Print "other thread: *"
'' Launch another thread
Dim As Any Ptr thread = ThreadCreate(@mythread, 0)
'' Work (main thread)
print_dots(".")
'' Wait until other thread has finished, if needed
ThreadWait(thread)
Print
Sleep
`
`
'' Threaded consumer/producer example using mutexes
Dim Shared As Any Ptr produced, consumed
Sub consumer( ByVal param As Any Ptr )
For i As Integer = 0 To 9
MutexLock produced
Print ", consumer gets:", i
Sleep 500
MutexUnlock consumed
Next
End Sub
Sub producer( ByVal param As Any Ptr )
For i As Integer = 0 To 9
Print "Producer puts:", i;
Sleep 500
MutexUnlock produced
MutexLock consumed
Next i
End Sub
Dim As Any Ptr consumer_id, producer_id
produced = MutexCreate
consumed = MutexCreate
If( ( produced = 0 ) Or ( consumed = 0 ) ) Then
Print "Error creating mutexes! Exiting..."
End 1
End If
MutexLock produced
MutexLock consumed
consumer_id = ThreadCreate(@consumer)
producer_id = ThreadCreate(@producer)
If( ( producer_id = 0 ) Or ( consumer_id = 0 ) ) Then
Print "Error creating threads! Exiting..."
End 1
End If
ThreadWait consumer_id
ThreadWait producer_id
MutexDestroy consumed
MutexDestroy produced
Sleep
`
Dialect Differences

- Threading is not allowed in the -lang qb dialect.

Platform Differences

- Threadcreate is not available with the DOS version / target of FreeBASIC, because multithreading is not supported by DOS kernel nor the used extender.
- In Linux the threads are always started in the order they are created, this can't be assumed in Win32. It's an OS, not a FreeBASIC issue.

Differences from QB

- New to FreeBASIC

See also

- `ThreadWait`
- `MutexCreate`
- `MutexLock`
- `MutexUnlock`
- `MutexDestroy`