CONDBROADCAST
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgCondBroadcast
- 最后更新: 2024-03-17
重新启动所有正在等待该句柄的 Condwait 线程
语法
declare sub Condbroadcast ( byval handle as any ptr )用法
Condbroadcast ( handle )参数
handle
条件变量的句柄。
说明
一旦使用 Condcreate 创建了条件变量并启动了线程,其中一个或多个线程(包括执行主程序的隐式主线程)可以被设置为对该条件变量执行 Condwait,它们将被阻塞,直到某个其他线程通过 Condsignal 通知等待线程可以继续执行。Condbroadcast 可用于重新启动所有等待该条件变量的线程。程序结束时必须使用 Conddestroy 来避免操作系统资源泄漏。
必须使用 Condbroadcast 而不是 Condsignal 来重新启动所有等待该条件变量的线程。
示例
另请参见 Condcreate
vb
'' 如何让所有线程在继续执行各自的并发代码段之前相互等待?
''
'' 这是管理并发代码段同步的主代码:
'' - 每个线程向主代码发信号,表示它正在等待同步。
'' - 主代码等待所有线程,然后向所有线程发送同步信号。
''
'' 同步使用以下线程关键字:
'' - 在每个线程中:'Condsignal'(向主代码发信号)然后 'Condwait'(等待主代码发信号)。
'' - 在主代码中:'Condwait'(等待每个线程发信号)然后 'Condbroadcast'(向所有线程发信号)。
'' 配合相关的互斥锁、条件变量和标志使用。
''
'' 测试示例,展示线程的结构及其在同步所有线程以执行各自并发代码段时的行为:
Dim threadnumber As Integer = 4
'' 所有线程的全局数据
Dim Shared restart As Integer = 0
Dim Shared threadcount As Integer = 0
Dim Shared hmutexrestart As Any Ptr
Dim Shared hcondrestart As Any Ptr
Dim Shared hmutexready As Any Ptr
Dim Shared hcondready As Any Ptr
Sub mythread(ByVal p As Any Ptr)
Dim id As Integer = Cast(Integer, p)
'' 可视化线程状态
Print " Thread #" & id & " is started..."
'' 代替启动用户代码
Sleep id * 40, 1
'' 可视化线程状态
Print " Thread #" & id & " is running..."
Sleep id * 20, 1 '' 仅用于直观显示线程交错
Print " Thread #" & id & " is waiting for synchronization..."
'' 向主代码发送信号
MutexLock hmutexready
threadcount += 1
CondSignal hcondready
MutexUnlock hmutexready
'' 等待主代码的信号
MutexLock hmutexrestart
Do While restart = 0
CondWait hcondrestart, hmutexrestart
Loop
MutexUnlock hmutexrestart
'' 可视化线程状态
Print " Thread #" & id & " is reactivated..."
'' 代替同步用户代码
Sleep id * 40, 1
'' 可视化线程状态
Print " Thread #" & id & " is continuing..."
Sleep id * 20, 1 '' 仅用于直观显示线程交错
Print " Thread #" & id & " is finishing execution..."
End Sub
Dim threads(1 To threadnumber) As Any Ptr
hcondrestart = CondCreate()
hmutexrestart = MutexCreate()
hcondready = CondCreate()
hmutexready = MutexCreate()
'' 可视化主代码状态
Print "Start all threads from main code :"
'' 启动所有线程
For i As Integer = 1 To threadnumber
threads(i) = ThreadCreate(@mythread, Cast(Any Ptr, i))
Next i
'' 等待所有线程进入同步等待状态
MutexLock hmutexready
Do Until threadcount = threadnumber
CondWait(hcondready, hmutexready)
Loop
MutexUnlock hmutexready
'' 可视化主代码状态
Print "All thread seen waiting from main code"
Print
Print "Reactivate all threads from main code :"
'' 重新激活所有线程
MutexLock hmutexrestart
restart = 1
CondBroadcast hcondrestart
MutexUnlock hmutexrestart
'' 等待所有线程完成
For i As Integer = 1 To threadnumber
If threads(i) <> 0 Then
ThreadWait threads(i)
End If
Next i
'' 可视化主代码状态
Print "All thread seen completed from main code"
MutexDestroy hmutexready
CondDestroy hcondready
MutexDestroy hmutexrestart
CondDestroy hcondrestart
Sleep平台差异
- Condbroadcast 在 FreeBASIC 的 DOS 版本/目标中不可用,因为 DOS 内核及其所使用的扩展器均不支持多线程。
- 在 Linux 中,线程始终按创建顺序启动,这在 Win32 中无法保证。这是操作系统的问题,而非 FreeBASIC 的问题。
方言差异
- 在 -lang qb 方言中不允许使用线程
与 QB 的区别
- FreeBASIC 新增功能
另请参见
CondcreateConddestroyCondsignalCondwaitThreadcreate
返回 目录