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 的舊值