Revision history for KeyPgThreadCreate


Revision [20550]

Last edited on 2016-02-10 16:09:28 by DkLwikki [Update link format]
Additions:
[[KeyPgDeclare|Declare]] [[KeyPgFunction|Function]] **Threadcreate** _
[[KeyPgByval|ByVal]] //procptr// [[KeyPgAs|As]] [[KeyPgSub|Sub]] ( [[KeyPgByval|ByVal]] //userdata// [[KeyPgAs|As]] [[KeyPgAny|Any]] [[KeyPgPtr|Ptr]] ), _
[[KeyPgByval|ByVal]] //param// [[KeyPgAs|As]] [[KeyPgAny|Any]] [[KeyPgPtr|Ptr]] = 0, _
[[KeyPgByval|ByVal]] //stack_size// [[KeyPgAs|As]] [[KeyPgInteger|Integer]] = 0 _
) [[KeyPgAs|As]] [[KeyPgAny|Any]] [[KeyPgPtr|Ptr]]
A pointer to the ##[[KeyPgSub|Sub]]## intended to work as a thread. The sub must have the following signature (same parameters, same calling convention) to be compatible to //procptr//:
##[[KeyPgDeclare|Declare]] [[KeyPgSub|Sub]] myThread ( [[KeyPgByval|ByVal]] //userdata// [[KeyPgAs|As]] [[KeyPgAny|Any]] [[KeyPgPtr|Ptr]] )##
The ##Any Ptr## parameter of the ##[[KeyPgSub|Sub]]## intended to work as a thread. ""FreeBASIC"" expects this parameter to be present, it must not be omitted!
##Any Ptr## argument that will be passed to the thread ##[[KeyPgSub|Sub]]## pointed to by ##//procptr//## through its //userdata// parameter. For example, this can be a pointer to a structure or an array containing various information for the thread sub to work with. If //param// is not given, ##0## (zero) will be passed to the thread sub's //userdata// parameter instead.
Before closing, programs should wait for the termination of all launched threads by using ##[[KeyPgThreadWait|ThreadWait]]##. Alternatively, if it's not necessary to safely wait for a thread to finish execution, ##[[KeyPgThreadDetach|ThreadDetach]]## can be used. However, if a program exits while some threads are still active, those threads will be aborted by the system. For every thread created, programs should call either ##[[KeyPgThreadWait|ThreadWait]]## or ##[[KeyPgThreadDetach|ThreadDetach]]## to ensure that the system resources associated with the thread handles are released. Otherwise, there may be memory or system resource leaks.
Due to the nature of threads, no assumptions about execution order can be made. In order to exchange data between multiple threads, including a thread and the main part of the program, mutexes must be used. These mutual exclusion locks can be "owned" by a single thread while doing critical work, causing other threads to wait for their turn. See ##[[KeyPgMutexCreate|Mutexcreate]]##, ##[[KeyPgMutexLock|Mutexlock]]##, ##[[KeyPgMutexUnlock|Mutexunlock]]##, ##[[KeyPgMutexDestroy|Mutexdestroy]]##.
- Threading is not allowed in the //[[CompilerOptlang|-lang qb]]// dialect.
- ##[[KeyPgThreadWait|ThreadWait]]##
- ##[[KeyPgThreadDetach|ThreadDetach]]##
- ##[[KeyPgMutexCreate|Mutexcreate]]##
- ##[[KeyPgMutexLock|Mutexlock]]##
- ##[[KeyPgMutexUnlock|Mutexunlock]]##
- ##[[KeyPgMutexDestroy|Mutexdestroy]]##
Deletions:
[[KeyPgDeclare Declare]] [[KeyPgFunction Function]] **Threadcreate** _
[[KeyPgByval ByVal]] //procptr// [[KeyPgAs As]] [[KeyPgSub Sub]] ( [[KeyPgByval ByVal]] //userdata// [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]] ), _
[[KeyPgByval ByVal]] //param// [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]] = 0, _
[[KeyPgByval ByVal]] //stack_size// [[KeyPgAs As]] [[KeyPgInteger Integer]] = 0 _
) [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]]
A pointer to the ##[[KeyPgSub Sub]]## intended to work as a thread. The sub must have the following signature (same parameters, same calling convention) to be compatible to //procptr//:
##[[KeyPgDeclare Declare]] [[KeyPgSub Sub]] myThread ( [[KeyPgByval ByVal]] //userdata// [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]] )##
The ##Any Ptr## parameter of the ##[[KeyPgSub Sub]]## intended to work as a thread. ""FreeBASIC"" expects this parameter to be present, it must not be omitted!
##Any Ptr## argument that will be passed to the thread ##[[KeyPgSub Sub]]## pointed to by ##//procptr//## through its //userdata// parameter. For example, this can be a pointer to a structure or an array containing various information for the thread sub to work with. If //param// is not given, ##0## (zero) will be passed to the thread sub's //userdata// parameter instead.
Before closing, programs should wait for the termination of all launched threads by using ##[[KeyPgThreadWait ThreadWait]]##. Alternatively, if it's not necessary to safely wait for a thread to finish execution, ##[[KeyPgThreadDetach ThreadDetach]]## can be used. However, if a program exits while some threads are still active, those threads will be aborted by the system. For every thread created, programs should call either ##[[KeyPgThreadWait ThreadWait]]## or ##[[KeyPgThreadDetach ThreadDetach]]## to ensure that the system resources associated with the thread handles are released. Otherwise, there may be memory or system resource leaks.
Due to the nature of threads, no assumptions about execution order can be made. In order to exchange data between multiple threads, including a thread and the main part of the program, mutexes must be used. These mutual exclusion locks can be "owned" by a single thread while doing critical work, causing other threads to wait for their turn. See ##[[KeyPgMutexCreate Mutexcreate]]##, ##[[KeyPgMutexLock Mutexlock]]##, ##[[KeyPgMutexUnlock Mutexunlock]]##, ##[[KeyPgMutexDestroy Mutexdestroy]]##.
- Threading is not allowed in the //[[CompilerOptlang -lang qb]]// dialect.
- ##[[KeyPgThreadWait ThreadWait]]##
- ##[[KeyPgThreadDetach ThreadDetach]]##
- ##[[KeyPgMutexCreate Mutexcreate]]##
- ##[[KeyPgMutexLock Mutexlock]]##
- ##[[KeyPgMutexUnlock Mutexunlock]]##
- ##[[KeyPgMutexDestroy Mutexdestroy]]##


Revision [17067]

Edited on 2014-04-28 09:00:27 by DkLwikki [Mention ThreadDetach & explain more]
Additions:
**""ThreadCreate""** returns an ##Any Ptr## handle to the thread created, or a null pointer (##0##) on failure.
Before closing, programs should wait for the termination of all launched threads by using ##[[KeyPgThreadWait ThreadWait]]##. Alternatively, if it's not necessary to safely wait for a thread to finish execution, ##[[KeyPgThreadDetach ThreadDetach]]## can be used. However, if a program exits while some threads are still active, those threads will be aborted by the system. For every thread created, programs should call either ##[[KeyPgThreadWait ThreadWait]]## or ##[[KeyPgThreadDetach ThreadDetach]]## to ensure that the system resources associated with the thread handles are released. Otherwise, there may be memory or system resource leaks.
- ##[[KeyPgThreadWait ThreadWait]]##
- ##[[KeyPgThreadDetach ThreadDetach]]##
Deletions:
**Threadcreate** returns an ##Any Ptr## handle to the thread created, or a null pointer (##0##) on failure.
Before closing, a program must wait for the termination of all the threads it has launched; see ##[[KeyPgThreadWait Threadwait]]##.
- ##[[KeyPgThreadWait Threadwait]]##


Revision [16723]

Edited on 2013-04-23 12:41:30 by DkLwikki [Overhaul; mention required userdata parameter]
Additions:
[[KeyPgDeclare Declare]] [[KeyPgFunction Function]] **Threadcreate** _
( _
[[KeyPgByval ByVal]] //procptr// [[KeyPgAs As]] [[KeyPgSub Sub]] ( [[KeyPgByval ByVal]] //userdata// [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]] ), _
[[KeyPgByval ByVal]] //param// [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]] = 0, _
[[KeyPgByval ByVal]] //stack_size// [[KeyPgAs As]] [[KeyPgInteger Integer]] = 0 _
) [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]]
//result// = **Threadcreate** ( //procptr// [, [ //param// ] [, //stack_size// ] ] )
##//procptr//##
A pointer to the ##[[KeyPgSub Sub]]## intended to work as a thread. The sub must have the following signature (same parameters, same calling convention) to be compatible to //procptr//:
##[[KeyPgDeclare Declare]] [[KeyPgSub Sub]] myThread ( [[KeyPgByval ByVal]] //userdata// [[KeyPgAs As]] [[KeyPgAny Any]] [[KeyPgPtr Ptr]] )##
##//userdata//##
The ##Any Ptr## parameter of the ##[[KeyPgSub Sub]]## intended to work as a thread. ""FreeBASIC"" expects this parameter to be present, it must not be omitted!
##Any Ptr## argument that will be passed to the thread ##[[KeyPgSub Sub]]## pointed to by ##//procptr//## through its //userdata// parameter. For example, this can be a pointer to a structure or an array containing various information for the thread sub to work with. If //param// is not given, ##0## (zero) will be passed to the thread sub's //userdata// parameter instead.
**Threadcreate** returns an ##Any Ptr## handle to the thread created, or a null pointer (##0##) on failure.
The sub pointed to by //procptr// is started as a thread. It will be passed the content of //param//, or 0 (zero) if not specified, in its //userdata// parameter.
The sub that was started as a thread will execute in parallel with the main part of the program. The OS achieves this by assigning it to a different processor if it exists, or by alternating between execution threads on a single processor. There is no guarantee about the order in which different threads execute, and no assumptions can be made about the order in which multiple create threads actually start executing.
Due to the nature of threads, no assumptions about execution order can be made. In order to exchange data between multiple threads, including a thread and the main part of the program, mutexes must be used. These mutual exclusion locks can be "owned" by a single thread while doing critical work, causing other threads to wait for their turn. See ##[[KeyPgMutexCreate Mutexcreate]]##, ##[[KeyPgMutexLock Mutexlock]]##, ##[[KeyPgMutexUnlock Mutexunlock]]##, ##[[KeyPgMutexDestroy Mutexdestroy]]##.
##//stack_size//## can be used to change the thread's stack size from the system's default. This can be useful when the program requires a big stack, for example due to lots of procedure recursion or when allocating huge strings/arrays on the stack. On some systems (Linux), the stack automatically grows beyond ##//stack_size//## if more space is needed; on others (Win32), 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.
Deletions:
[[KeyPgDeclare declare]] [[KeyPgFunction function]] **Threadcreate** ( [[KeyPgByval byval]] //proc// [[KeyPgAs as]] [[KeyPgSub sub]] ( [[KeyPgByval byval]] [[KeyPgAs as]] [[KeyPgAny any]] [[KeyPgPtr ptr]] ), [[KeyPgByval byval]] //param// [[KeyPgAs as]] [[KeyPgAny any]] [[KeyPgPtr ptr]] = 0, [[KeyPgByval byval]] //stack_size// [[KeyPgAs as]] [[KeyPgInteger integer]] = 0 ) [[KeyPgAs as]] [[KeyPgAny any]] [[KeyPgPtr ptr]]
//result// = **Threadcreate** ( //proc// [, [ //param// ] [, //stack_size// ] ] )
##//proc//##
A pointer to the ##[[KeyPgSub Sub]]## intended to work as a thread.
Optional [[KeyPgAny any]] [[KeyPgPtr ptr]] argument for the ##[[KeyPgSub Sub]]## pointed to by ##//proc//## (it can be a pointer to a structure or an array if more arguments are needed).
**Threadcreate** returns an ##[[KeyPgAny any]] [[KeyPgPtr ptr]]## handle to the thread created, or the null pointer (##0##) on failure.
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.
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 ##[[KeyPgMutexCreate Mutexcreate]]##, ##[[KeyPgMutexLock Mutexlock]]##, ##[[KeyPgMutexUnlock Mutexunlock]]##, ##[[KeyPgMutexDestroy 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.


Revision [16218]

Edited on 2012-07-11 15:16:45 by CountingPine [Example code: comment typo, style consistency]
Additions:
'' Threading synchronization using Mutexes
Dim Shared As Any Ptr ttylock
Sub teletype( ByRef text As String, ByVal x As Integer, ByVal y As Integer )
Deletions:
'' Threading syncronyzation using Mutexes
Dim Shared As Any ptr ttylock
Sub teletype( text As String, x As Integer, y As Integer )


Revision [15569]

Edited on 2011-12-17 14:58:47 by CountingPine [##0##]
Additions:
**Threadcreate** returns an ##[[KeyPgAny any]] [[KeyPgPtr ptr]]## handle to the thread created, or the null pointer (##0##) on failure.
Deletions:
**Threadcreate** returns an ##[[KeyPgAny any]] [[KeyPgPtr ptr]]## handle to the thread created, or the null pointer (0) on failure.


Revision [15555]

Edited on 2011-12-15 09:50:09 by CountingPine [##0##]
Additions:
- Threading is not allowed in the //[[CompilerOptlang -lang qb]]// dialect.
Deletions:
- Threading is not allowed in ##-lang qb##


Revision [15297]

Edited on 2011-10-01 07:11:28 by DkLwikki [Update & add more examples]
Additions:
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 ##[[KeyPgMutexCreate Mutexcreate]]##, ##[[KeyPgMutexLock Mutexlock]]##, ##[[KeyPgMutexUnlock Mutexunlock]]##, ##[[KeyPgMutexDestroy Mutexdestroy]]##.
Deletions:
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 ##[[KeyPgMutexCreate Mutexcreate]]##, ##[[KeyPgMutexLock Mutexlock]]##, ##[[KeyPgMutexUnlock Mutexunlock]]##, ##[[KeyPgMutexDestroy Mutexdestroy]]##.


Revision [15287]

Edited on 2011-10-01 07:06:00 by DkLwikki [Update & add more examples]

No Differences

Revision [15286]

Edited on 2011-10-01 07:05:37 by DkLwikki [Update & add more examples]
Additions:
{{fbdoc item="filename" value="examples/manual/threads/threads3.bas"}}%%(freebasic)
'' 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
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
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


Revision [15283]

Edited on 2011-10-01 02:53:33 by DkLwikki [Update example, add second one]
Additions:
{{fbdoc item="filename" value="examples/manual/threads/threads1.bas"}}%%(freebasic)
'' Threading syncronyzation 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( text As String, x As Integer, 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
Sub thread( ByVal userdata As Any Ptr )
Dim As Integer id = CInt(userdata)
teletype "Thread (" & id & ").........", 1 + id, 1
'' 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)
{{fbdoc item="filename" value="examples/manual/threads/threads2.bas"}}%%(freebasic)
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
- **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.
Deletions:
{{fbdoc item="filename" value="examples/manual/threads/threadcreate.bas"}}%%(freebasic)
Dim Shared terminate As Integer = 0
Sub mythread (param As Any Ptr)
dim as double t = timer
While( 1 )

Print "*";

'' pause for .1 second
while( abs( timer - t ) < .1 )
sleep 1, 1
wend
t = timer

If terminate=1 Then Exit Sub
Wend
Dim thread As Any Ptr
Dim b As Integer
dim as double t
Print "Main program prints dots"
Print "Thread prints asterisks"
thread = ThreadCreate( @mythread, 0 )
Print "Thread launched";
While b < 30
Print ".";
'' pause for .1 second
while( abs( timer - t ) < .1 )
sleep 1, 1
wend
t = timer
b += 1
Wend
terminate=1
Print "Terminate launched";
ThreadWait (thread)
Print "Thread terminated"
Sleep
- **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.


Revision [14449]

Edited on 2009-08-29 21:57:13 by CountingPine [Remove CamelCase links in "New to FreeBASIC"]
Additions:
- New to ""FreeBASIC""
Deletions:
- New to FreeBASIC


Revision [13528]

The oldest known version of this page was created on 2008-07-16 15:47:54 by ChA0s [Remove CamelCase links in "New to FreeBASIC"]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki



sf.net phatcode