Skip to content

CONDBROADCAST


重新启动所有正在等待该句柄的 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 新增功能

另请参见

  • Condcreate
  • Conddestroy
  • Condsignal
  • Condwait
  • Threadcreate

返回 目录

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