BlitzMax/Modules/System/Threads
欢迎来到多线程的奇妙世界!
多线程实际上允许您的程序同时执行多项任务。在此上下文中,“线程”指的是“执行线程” - 或者,您的程序执行的一系列指令、分支等等。大多数程序都是“单线程”的,这意味着只有一条执行线程。但是,越来越多的程序正在使用多线程。
多线程曾经是通过软件技巧实现的,这使得多线程变得有用,但并没有真正加快速度 - 仍然只有一个 CPU 假装同时执行多项任务!但是如今,多核 CPU 意味着多线程可以真正地同时执行多项任务(或“并行”)。
创建线程很容易 - 只需调用 CreateThread 即可。您需要为线程提供一个用作其“入口点”的函数。创建线程后,该函数将与调用 CreateThread 的代码并行执行。当线程函数返回时,该线程将“终止”。
唉,多线程由于一个称为“同步”的问题而变得相当棘手。当您需要防止多个线程同时修改或访问相同的数据时,需要同步。同步通常涉及线程“阻塞”。当线程阻塞时,它会完全停止执行,直到另一个线程执行导致它“解除阻塞”并恢复执行的操作。
BlitzMax 提供了两个称为“互斥锁”和“信号量”的基本原语来帮助同步。
- 互斥锁提供了一个简单的锁定机制。一次只有一个线程可以锁定一个互斥锁(使用 LockMutex 或 TryLockMutex),因此这是一种轻松保护资源免受同时访问的方法。如果一个线程调用 LockMutex 并且互斥锁已被另一个线程锁定,则当前线程将阻塞,直到另一个线程使用 UnlockMutex 释放互斥锁。因此,请不要忘记在完成互斥锁后使用 UnlockMutex 释放它!
- 信号量提供了一种同步计数机制,并包含一个内部整数计数器。您可以对信号量执行两种操作 - 发送和等待。发送信号量(使用 PostSemaphore)会导致信号量的内部计数器递增,而等待信号量(使用 WaitSemaphore)会导致当前线程阻塞,直到信号量的内部计数器大于 0。当计数器大于 0 时,计数器会递减,并且线程会解除阻塞。信号量对于生产者/消费者类型的情况非常有用。
线程类型
- Detach
- Wait
- Running
- Create
- Main
- Current
方法 Detach()
描述:分离此线程
方法 Wait:Object()
描述:等待此线程完成
返回值:线程返回的对象。
方法 Running()
描述:检查此线程是否正在运行
函数 Create:TThread( entry:Object( data:Object),data:Object )
描述:创建一个新线程
函数 Main:TThread()
描述:获取主线程
返回值:一个表示主应用程序线程的线程对象。
函数 Current:TThread()
描述:获取当前线程
返回值:一个表示当前线程的线程对象。
线程数据类型
- SetValue
- GetValue
- Create
方法 SetValue( value:Object )
描述:设置线程数据值
方法 GetValue:Object()
描述:获取线程数据值
函数 Create:TThreadData()
描述:创建线程数据
互斥锁类型
- Close
- Lock
- TryLock
- Unlock
- Create
方法 Close()
描述:关闭互斥锁
方法 Lock()
描述:锁定互斥锁
方法 TryLock()
描述: 尝试锁定互斥锁
返回值: 如果互斥锁成功锁定,则返回 True;如果互斥锁已被另一个线程锁定,则返回 False。
方法 Unlock()
描述: 解锁互斥锁
函数 Create:TMutex()
描述: 创建一个新的互斥锁
信号量类型
- Close
- Wait
- Post
- Create
方法 Close()
描述: 关闭信号量
方法 Wait()
描述: 等待信号量
方法 Post()
描述: 发布信号量
函数 Create:TSemaphore( count )
描述: 创建一个新的信号量
条件变量类型
- Close
- Wait
- Signal
- Broadcast
- Create
方法 Close()
描述: 关闭条件变量
方法 Wait( mutex:TMutex )
描述: 等待条件变量
方法 Signal()
描述: 通知条件变量
方法 Broadcast()
描述: 广播条件变量
函数 Create:TCondVar()
描述: 创建一个新的条件变量
函数 CreateThread:TThread( entry:Object( data:Object ),data:Object )
描述: 创建一个线程
返回值: 一个新的线程对象。
信息: 创建一个线程并返回一个线程对象。
线程 entry 例程返回的值可以通过 WaitThread 检索。
要“关闭”线程,请调用 DetachThread 或 WaitThread。这并不是严格必要的,因为线程最终会在垃圾回收时被关闭,但是,如果您经常创建很多线程,这是一个好主意,因为某些操作系统对一次可以分配的线程数量有限制。
示例:
'Make sure to have 'Threaded build' enabled! ' Strict 'Custom print that shows which thread is doing the printing Function MyPrint( t$ ) If CurrentThread()=MainThread() Print "Main thread: "+t Else Print "Child thread: "+t EndIf End Function 'Our thread function Function MyThread:Object( data:Object ) 'show data we were passed Myprint data.ToString() 'do some work For Local i=1 To 1000 MyPrint "i="+i Next 'return a value from the thread Return "Data returned from child thread." End Function MyPrint "About to start child thread." 'create a thread! Local thread:TThread=CreateThread( MyThread,"Data passed to child thread." ) 'wait for thread to finish and print value returned from thread MyPrint WaitThread( Thread ).ToString()
函数 MainThread:TThread()
描述:获取主线程
返回值: 一个表示主应用程序线程的线程对象。
函数 CurrentThread:TThread()
描述:获取当前线程
返回值:一个表示当前线程的线程对象。
函数 DetachThread( thread:TThread )
描述: 分离线程
信息: DetachThread 关闭线程句柄,但不停止或以其他方式影响目标线程。
一旦线程被分离,就无法再使用 WaitThread 获取其返回值。
这允许线程运行,而无需您的程序不断检查它是否已完成以关闭它。
函数 WaitThread:Object( thread:TThread )
描述: 等待线程完成
返回值: 线程入口例程返回的对象。
信息: WaitThread 导致调用线程阻塞,直到目标线程完成执行。
如果目标线程已经完成执行,WaitThread 会立即返回。
返回的对象是线程入口例程返回的对象,该对象传递给 CreateThread。
函数 ThreadRunning( thread:TThread )
描述: 检查线程是否正在运行
返回值: 如果 thread 仍在运行,则返回 True,否则返回 False。
函数 CreateThreadData:TThreadData()
描述:创建线程数据
返回值: 一个新的线程数据对象。
函数 SetThreadDataValue( data:TThreadData,value:Object )
描述:设置线程数据值
函数 GetThreadDataValue:Object( data:TThreadData )
描述:获取线程数据值
函数 CreateMutex:TMutex()
描述: 创建一个互斥锁
返回值: 一个新的互斥锁对象
示例:
'Make sure to have 'Threaded build' enabled! ' Strict 'a global list that multiple threads want to modify Global list:TList=New TList 'a mutex controlling access to the global list Global listMutex:TMutex=CreateMutex() Function MyThread:Object( data:Object ) For Local item=1 To 10 'simulate 'other' processing... Delay Rand( 10,50 ) 'lock mutex so we can safely modify global list LockMutex listMutex 'modify list list.AddLast "Thread "+data.ToString()+" added item "+item 'unlock mutex UnlockMutex listMutex Next End Function Local threads:TThread[10] 'Create worker threads For Local i=0 Until 10 threads[i]=CreateThread( MyThread,String( i+1 ) ) Next Print "Waiting for worker threads..." 'Wait for worker threads to finish For Local i=0 Until 10 WaitThread threads[i] Next 'Show the resulting list ' 'Note: We don't really have to lock the mutex here, as there are no other threads running. 'Still, it's a good habit to get into. LockMutex listMutex For Local t$=EachIn list Print t Next UnlockMutex listMutex
函数 CloseMutex( mutex:TMutex )
描述: 关闭互斥锁
函数 LockMutex( mutex:TMutex )
描述: 锁定互斥锁
函数 TryLockMutex( mutex:TMutex )
描述: 尝试锁定互斥锁
返回值: 如果 mutex 成功锁定,则返回 True;如果 mutex 已被另一个线程锁定,则返回 False。
函数 UnlockMutex( mutex:TMutex )
描述: 解锁互斥锁
Function CreateSemaphore:TSemaphore( count )
描述: 创建一个信号量
返回值: 一个新的信号量对象
示例:
'Make sure to have 'Threaded build' enabled! ' Strict 'a simple queue Global queue$[100],put,get 'a counter semaphore Global counter:TSemaphore=CreateSemaphore( 0 ) Function MyThread:Object( data:Object ) 'process 100 items For Local item=1 To 100 'add an item to the queue queue[put]="Item "+item put:+1 'increment semaphore count. PostSemaphore counter Next End Function 'create worker thread Local thread:TThread=CreateThread( MyThread,Null ) 'receive 100 items For Local i=1 To 100 'Wait for semaphore count to be non-0, then decrement. WaitSemaphore counter 'Get an item from the queue Local item$=queue[get] get:+1 Print item Next
Function CloseSemaphore( semaphore:TSemaphore )
描述: 关闭一个信号量
Function WaitSemaphore( semaphore:TSemaphore )
描述: 等待一个信号量
Function PostSemaphore( semaphore:TSemaphore )
描述: 发送一个信号量
Function CreateCondVar:TCondVar()
描述: 创建一个条件变量
返回值: 一个新的条件变量对象
Function CloseCondVar( condvar:TCondVar )
描述: 关闭一个条件变量
Function WaitCondVar( condvar:TCondVar,mutex:TMutex )
描述: 等待一个条件变量
Function SignalCondVar( condvar:TCondVar )
描述: 通知一个条件变量
Function BroadcastCondVar( condvar:TCondVar )
描述: 广播一个条件变量
Function CompareAndSwap( target Var,oldValue,newValue )
描述: 比较并交换
返回值: 如果 target 被更新则返回 True
信息: 如果 target 等于 old_value,则以原子方式将 target 替换为 new_value。
Function AtomicAdd( target Var,value )
描述: 原子加法
返回值: target 的先前值
信息: 以原子方式将 value 添加到 target。
Function AtomicSwap( target Var,value )
描述: 原子交换值
返回值: target 的旧值