创建用于同步线程执行的互斥体
语法
用法
result = MutexCreate
返回值
说明
互斥是“互斥”的缩写,是在线程中同步共享数据的一种方法。如果有多个线程使用的全局变量(或单个线程使用的局部变量,多次调用),则在使用互斥体时应该将其“锁定”。这将使用
MutexLock使用该互斥体(包括执行主程序的主线程)停止所有线程,直到使用
MutexUnlock解锁。
Mutexcreate创建互斥体,返回在锁定,解锁或销毁互斥体时要引用的句柄。使用
Mutexcreate创建的互斥体在不再需要时或在
MutexDestroy程序结束之前应该被销毁。
互斥是一个锁,保证三件事情:
1.原子性 - 锁定互斥体是一个原子操作,这意味着操作系统(或线程库)可以确保您锁定互斥体,但没有其他线程成功地同时锁定该互斥体。
2.奇异性 - 如果一个线程设法锁定一个互斥体,那么确保没有其他线程将能够锁定线程,直到原来的线程释放锁定。
3.非忙等待 - 如果线程尝试锁定被第二个线程锁定的线程,则第一个线程将被挂起(并且不会占用任何CPU资源),直到锁被第二个线程释放。此时,第一个线程将唤醒并继续执行,将互斥锁锁定在其上。
例子
另见
ThreadCreate示例。
'使用Mutex进行线程同步的可视示例:
'“用户定义的线程”计算圆上的点坐标,
'和“主线程”绘制点数。
'
'如果你注释掉包含“MutexLock”和“MutexUnlock”的行
'(在“用户定义的线程”或/和“主线程”内),
'两个线程(“用户定义”和“主”)将不会同步,
'并且许多点不会在圆上绘制(由于非相干坐标)。
'-----------------------------------------------------------------------------------------------------
Type ThreadUDT '通用用户线程UDT
Dim handle As Any Ptr '任何用户线程的Ptr句柄
Dim sync As Any Ptr '互斥体的任何Ptr句柄
Dim quit As Byte '布尔到最终用户线程
Declare Static Sub Thread (ByVal As Any Ptr) '通用用户线程程序
Dim procedure As Sub (ByVal As Any Ptr) '用户线程执行的过程(任何Ptr)
Dim p As Any Ptr '任何Ptr传递给用户线程执行的过程
Const false As Byte = 0 '常数“假”
Const true As Byte = Not False '康斯坦丁“真”
End Type
Static Sub ThreadUDT.Thread (ByVal param As Any Ptr) '通用用户线程程序
Dim tp As ThreadUDT Ptr = param '转换为通用用户线程UDT
Do
MutexLock(tp->sync) '互斥(锁定)用户线程
tp->procedure(tp->p) '用户线程执行的过程(任何Ptr)
MutexUnlock(tp->sync) 'Mutex(解锁)用户线程
Sleep 5
Loop Until tp->quit = tp->true '测试结束用户线程
End Sub
'-----------------------------------------------------------------------------------------------------
Type Point2D
Dim x As Integer
Dim y As Integer
End Type
Const x0 As Integer = 640 / 2
Const y0 As Integer = 480 / 2
Const r0 As Integer = 200
Const pi As Single = 4 * Atn(1)
Sub PointOnCircle (ByVal p As Any Ptr)
Dim pp As Point2D Ptr = p
Dim teta As Single = 2 * pi * Rnd
pp->x = x0 + r0 * Cos(teta)
Sleep 5 '增加不相关的数据发生的可能性
pp->y = y0 + r0 * Sin(teta)
End Sub
Screen 12
Locate 30, 2
Print "<any_key >:exit";
Dim Pptr As Point2D Ptr = New Point2D
Pptr->x = x0 + r0 * Cos(0)
pptr->y = y0 + r0 * Sin(0)
Dim Tptr As ThreadUDT Ptr = New ThreadUDT
Tptr->sync = MutexCreate
Tptr->procedure = @PointOnCircle
Tptr->p = Pptr
Tptr->handle = ThreadCreate(@ThreadUDT.Thread, Tptr)
Do
MutexLock(Tptr->sync) '用于主线程的互斥(锁定)
PSet (Pptr->x, Pptr->y)
MutexUnlock(Tptr->sync) 'Mutex(解锁)主线程
Sleep 5
Loop Until Inkey <> ""
Tptr->quit = Tptr->true
ThreadWait(Tptr->handle)
MutexDestroy(Tptr->sync)
Delete Tptr
Delete Pptr
方言差异
平台差异
- FreeBASIC的DOS版本不允许线程,因为操作系统不支持它们。
- 在Linux中,线程始终按照创建的顺序启动,这在Win32中是不可以假定的。这是一个操作系统,而不是FreeBASIC的问题。
与QB差别
参考