临界区
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgMtCriticalSections
- 最后更新: 2023-05-02
在临界区中正确使用内置过程来处理与其他线程的并发。
前言:
临界区是多线程程序中必须作为原子操作执行的部分(不允许与执行类似操作的其他线程并发):
它是程序中需要互斥访问的代码段。
通常,临界区访问共享资源,例如数据结构、外围设备或网络连接,这些资源不允许多个并发访问。
当程序启动时,一个线程已经立即开始运行。这通常被称为程序的"主"线程,因为它是程序开始时执行的线程:
它是用户可以从中派生其他"子"线程的线程(子线程又可以派生其他"孙"线程)。
通常,它必须是最后一个完成执行的线程,因为它执行各种关闭操作(子线程也必须对其派生的"孙"线程进行同样的操作)。
但除此之外,它也可以与用户显式派生的所有其他线程竞争(拥有自己的临界区)。
基本算法
使用 FreeBASIC 提供的内置过程,确保临界区独占使用的方法可以设计为适用于线程的异步或同步算法。
- 使用互斥锁的异步方法基本算法:
- 使用 condwait 然后 condsignal/condbroadcast(以及互斥锁)的同步方法基本算法:
示例
在以下两个示例中,共享资源是输入/输出显示设备:
为 6 个用户线程中的每一个打印其计数器(并读取标志
'quit')。捕获主线程的按键(任意一个)(如果是,则将标志
'quit'设置为'true')。
输出过程('Sub Counter()')故意在光标定位和打印之间加入了延迟,并在结束前将文本光标重新定位到行中间,以彻底检查临界区执行之间没有重叠(相反,可以通过删除一些专用于互斥处理的代码来查看结果)。
在每个线程循环结束时设置不同的延迟值(从小到大)。
一个结构(UDT)将线程所需的所有变量分组。在创建阶段(使用 threadcreate)将指向每个 UDT 实例的指针传递给每个线程。
- 对所有线程使用一个互斥锁的异步方法示例:
- 对所有线程使用 condwait 然后 condbroadcast(以及一个互斥锁)的同步方法示例:
- 使用每个线程独立互斥锁,通过自锁和互解锁的奇特同步算法:
另请参阅
返回 目录