THREADSELF
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgThreadSelf
- 最后更新: 2021-10-11
返回当前线程的线程句柄。
语法
Declare Function ThreadSelf ( ) As Any Ptr用法
#include "fbthread.bi"
result = ThreadSelf返回值
ThreadSelf 返回当前线程的 Any Ptr 句柄。
说明
ThreadSelf 用于获取当前线程的句柄。
此函数可以唯一标识现有线程:
如果存在多个线程,且某个线程已完成,则该句柄可以被重用。
因此,对于所有仍在运行的线程,句柄是唯一的。
创建新线程时,创建函数会返回该线程的句柄。
当线程运行代码时,ThreadSelf 允许返回该线程的句柄(隐式主线程也有其自己的唯一句柄)。
ThreadSelf 可用于基于每个线程(包括隐式主线程)的唯一句柄实现某种 TLS(线程本地存储)。
因此,可以定义相同的全局变量名,但具有特定于访问它的线程的存储值。
这允许编写通用过程,但其参数取决于执行它的线程(见下面的第3个示例)。
示例
start GeSHi
vb
#include "fbthread.bi"
Dim As Any Ptr phandle(1 To 10)
Sub myThread (ByVal p As Any Ptr)
Print "Thread handle: " & Threadself()
End Sub
For I As Integer = 1 To 10
phandle(I) = ThreadCreate(@myThread)
Next I
For I As Integer = 1 To 10
ThreadWait(phandle(I))
Next I
Sleepend GeSHi
在线程创建时由 ThreadCreate 返回的线程句柄与线程运行时由 ThreadSelf 返回的句柄之间的相等性检查:
start GeSHi
vb
#include "fbthread.bi"
Dim As Any Ptr phandle(1 To 10)
Dim Shared As Any Ptr pmutex
Sub myThread (ByVal p As Any Ptr)
MutexLock(pmutex) ' to ensure that ThreadCreate line is completed before accessing the handle value
Dim As Any Ptr phandle1 = *CPtr(Any Ptr Ptr, p)
MutexUnlock(pmutex)
Dim As Any Ptr phandle2 = Threadself()
Print Left(" ThreadCreate: " & phandle1 & Space(18), 36) _
& " ThreadSelf: " & phandle2 ' single print with concatenated string avoids using a mutex
Sleep 100, 1
End Sub
Print "Handles returned from:"
pmutex = MutexCreate()
For I As Integer = 1 To 10
MutexLock(pmutex) ' to ensure that ThreadCreate line is completed before thread accesses the handle value
phandle(I) = ThreadCreate(@myThread, @phandle(I))
MutexUnlock(pmutex)
Next I
For I As Integer = 1 To 10
ThreadWait(phandle(I))
Next I
MutexDestroy(pmutex)
Sleepend GeSHi
TLS(线程本地存储)示例:
(见"说明"段落末尾)
start GeSHi
vb
#include once "fbthread.bi"
Function TLSindex() As Integer ' returning a unique thread index (incremented with each new thread)
Static As Any Ptr TLSind()
Dim As Integer index = -1
For I As Integer = LBound(TLSind) To UBound(TLSind)
If TLSind(I) = Threadself() Then
index = I
Exit For
End If
Next I
If index = -1 Then
index = UBound(TLSind) + 1
ReDim Preserve TLSind(index)
TLSind(index) = Threadself()
End If
Return index
End Function
Function TLSinteger() ByRef As Integer ' emulation of global integer with value depending on thread using it
Static As Integer TLSint()
Dim As Integer index = TLSindex()
If index > UBound(TLSint) Then
ReDim Preserve TLSint(index)
End If
Return TLSint(index)
End Function
'------------------------------------------------------------------------------
Type threadData
Dim As Any Ptr handle
Dim As String prefix
Dim As String suffix
Dim As Double tempo
End Type
Function counter() As Integer ' definition of a generic counter with counting depending on thread calling it
TLSinteger() += 1
Return TLSinteger()
End Function
Sub Thread(ByVal p As Any Ptr)
Dim As threadData Ptr ptd = p
Dim As UInteger c
Do
c = counter()
Print ptd->prefix & c & ptd->suffix & " "; ' single print with concatenated string avoids using a mutex
Sleep ptd->tempo, 1
Loop Until c = 12
End Sub
'------------------------------------------------------------------------------
Print "|x| : counting from thread a"
Print "(x) : counting from thread b"
Print "[x] : counting from thread c"
Print
Dim As threadData mtlsa
mtlsa.prefix = "|"
mtlsa.suffix = "|"
mtlsa.tempo = 250
mtlsa.handle = ThreadCreate(@Thread, @mtlsa)
Dim As threadData mtlsb
mtlsb.prefix = "("
mtlsb.suffix = ")"
mtlsb.tempo = 150
mtlsb.handle = ThreadCreate(@Thread, @mtlsb)
Dim As threadData mtlsc
mtlsc.prefix = "["
mtlsc.suffix = "]"
mtlsc.tempo = 100
mtlsc.handle = ThreadCreate(@Thread, @mtlsc)
ThreadWait(mtlsa.handle)
ThreadWait(mtlsb.handle)
ThreadWait(mtlsc.handle)
Print
Print
Print "end of threads"
Sleepend GeSHi
版本
- 自 fbc 1.08.0 起
方言差异
- 在 -lang qb 方言中不允许使用线程。
平台差异
- ThreadSelf 在 FreeBASIC 的 DOS 版本中不可用,因为 DOS 内核及所用的扩展器不支持多线程。
与QB的区别
- FreeBASIC 新增
参见
ThreadCreate
返回 目录