Skip to content

THREADSELF


返回当前线程的线程句柄。

语法

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

Sleep

end 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)

Sleep

end 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"

Sleep

end GeSHi

版本

  • 自 fbc 1.08.0 起

方言差异

  • -lang qb 方言中不允许使用线程。

平台差异

  • ThreadSelf 在 FreeBASIC 的 DOS 版本中不可用,因为 DOS 内核及所用的扩展器不支持多线程。

与QB的区别

  • FreeBASIC 新增

参见

  • ThreadCreate

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系