多線程(VFB教程3-3)

  勇芳 2018-2-17 6958

此處為VisualFreeBasic編程教程(從零開始學或VB進階)的子章節部分,全部目錄點鏈接。

使用多線程非常簡單,就如同調用本地過程一樣,可以啟用任意個過程,必須是SUB

Dim 線程句柄 As Any Ptr = ThreadCreate(@線程過程, 參數)  '創建個線程,并且傳遞1個數字參數,只允許1個,必須是1個。

Threaddetach(線程句柄) '銷毀句柄,只是句柄,不會停止和殺死線程,必須要銷毀

Sub 線程過程(線程參數 As Integer) '只允許1個參數,而且必須是1個,是數字
  '這里線程要執行的代碼,過程執行完,這線程就退出了
End Sub

調用和啟動線程,平常使用時可以簡化到一句

Threaddetach ThreadCreate(Cast(Any Ptr,@線程過程),參數) '經典調用方法

這里加個 Cast 語句是變量類型轉換,可以避免編譯器警告??梢哉f是必須要加個,當然不加也不會出錯。

只能傳一個參數,是有點不方便,但也可以傳指針過去,實現多參數傳遞

Sub Myaaa() '
  Dim aa As Any Ptr = CAllocate(12) '申請內存,并清除內容全為 0
  '申請內存大小按參數來,自己算出多少,也可以大點,不能少,少了軟件可能會崩潰
  CPtr(Long Ptr, aa)[0] = 111
  CPtr(Long Ptr, aa)[1] = 222
  CPtr(Long Ptr, aa)[2] = 333
  Threaddetach ThreadCreate(Cast(Any Ptr, @線程過程), aa) '經典調用方法
End Sub
Sub 線程過程(線程參數 As Any Ptr) '只允許1個參數,而且必須是1個,是數字
  '這里線程要執行的代碼,過程執行完,這線程就退出了
  Print  CPtr(Long Ptr, 線程參數)[0],CPtr(Long Ptr, 線程參數)[1],CPtr(Long Ptr, 線程參數)[2] 
  
  Deallocate(線程參數) '釋放內存
End Sub

要是遇到字符,可不能直接,可以自己算尺寸,我們可以用類來傳,比較簡單,方便

Type ABCabc
    aaa As Long 
    bbb As ZString *50 '必須是 zString ,不可以是 String 
    ccc As WString *10 
    eee As Double  
End Type  
Sub Myaaa() '
  Dim aa As ABCabc Ptr = CAllocate(1, SizeOf(ABCabc)) '申請內存,并清除內容全為 0
  '申請內存大小按參數來,自己算出多少,也可以大點,不能少,少了軟件可能會崩潰
  aa->aaa = 100
  aa->bbb = "普通字符"
  aa->ccc = "寬字符"
  aa->eee = 123.123 
  Threaddetach ThreadCreate(Cast(Any Ptr, @線程過程), aa) '經典調用方法
End Sub
Sub 線程過程(aa As ABCabc Ptr) '只允許1個參數,而且必須是1個,是數字
  '這里線程要執行的代碼,過程執行完,這線程就退出了
  Print aa->aaa, aa->bbb, aa->ccc, aa->eee  
  
  Deallocate(aa) '釋放內存
End Sub


到這里結束吧,下面代碼沒測試,只是舉例可以這么做,新手排除不了錯誤,誤看。


下面等技術提高了再看吧,不建議新手處理。。

====================================================================================================================

只可以傳1個參數給線程,線程句柄不用后,必須釋放,就用 ThreadDetach ,只是釋放句柄,但不會終止線程

有個 ThreadWait 是等待線程完成,才執行下一行,除非特殊情況,不然失去了多線程的意義,很少用到。

還有個種方法創建線程,可以帶多個參數

''線程使用“ThreadCall”

Sub thread( id As String, tlock As Any Ptr, count As Integer )
    For i As Integer = 1 To count
        MutexLock tlock
        Print "線" & id;
        Locate , 20
        Print i & "/" & count
        MutexUnlock tlock
    Next
End Sub

Dim tlock As Any Ptr = MutexCreate()
Dim a As Any Ptr = ThreadCall thread("A", tlock, 6)
Dim b As Any Ptr = ThreadCall thread("B", tlock, 4)
ThreadWait a
ThreadWait b
MutexDestroy tlock
Print "全部完成(并且沒有Dim Shared?。?quot;

使用Threadcall是創建線程的更簡單的方法,并允許將數據傳遞到線程,而不會有全局變量或不是類型安全的指針。但是,ThreadCreate更有效率,應該用于創建大量線程的程序。

Function IsThreadAlive(ByVal dwThread As HANDLE ) As BOOL  
'判斷線程句柄是否被終止 , 如果終止返回FALSE,如果還活著返回TRUE 
    Dim bRet As BOOL ,ExitCode As Ulong 
        If GetExitCodeThread(dwThread,@ExitCode) Then
            If ExitCode = STILL_ACTIVE Then bRet = True
        End If
    Return bRet
End Function
’此函數已經在VFB函數庫里,不需要自己創建,直接調用

有時需要知道,線程是不是活著還是終止,就用以上函數

Dim cc As HANDLE Ptr '線程指針
cc= ThreadCreate(@abc,0) '經典調用方法
If  IsThreadAlive(*cc) Then  '*CC 取出的是線程句柄
End If
Threaddetach cc '釋放線程句柄
-------------------------------------------------
sub abc(aa as long)  '線程標準寫法
.....
end sub

假如,有多個線程使用的全局變量,那么,就可能發生問題了,1個讀1個寫。

(如果是單個數字變量,可以不用考慮,字符串、數組等,肯定出問題)

MutexCreate創建個互斥體來,讀寫全局變量時用MutexLock鎖定,過后用MutexUnlock解鎖。

'使用Mutex進行線程同步的可視示例:
'“用戶定義的線程”計算圓上的點坐標,
'和“主線程”繪制點數。
'
'如果你注釋掉包含“MutexLock”和“MutexUnlock”的行
'(在“用戶定義的線程”或/和“主線程”內),
'兩個線程(“用戶定義”和“主”)將不會同步,
'并且許多點不會在圓上繪制(由于非相干坐標)。

'-----------------------------------------------------------------------------------------------------

Type ThreadUDT                                   '通用用戶線程UDT
    Dim handle As Any Ptr                        '任何用戶線程的Ptr句柄
    Dim sync As Any Ptr                          '互斥體的任何Ptr句柄
    Dim quit As Byte                             '布爾到最終用戶線程
    Declare Static Sub Thread (ByVal As Any Ptr) '通用用戶線程程序
    Dim procedure As Sub (ByVal As Any Ptr)      '用戶線程執行的過程(任何Ptr)
    Dim p As Any Ptr                             '任何Ptr傳遞給用戶線程執行的過程
    Const false As Byte = 0                      '常數“假”
    Const true As Byte = Not False               '康斯坦丁“真”
End Type

Static Sub ThreadUDT.Thread (ByVal param As Any Ptr) '通用用戶線程程序
    Dim tp As ThreadUDT Ptr = param                  '轉換為通用用戶線程UDT
    Do
        MutexLock(tp->sync)                          '互斥(鎖定)用戶線程
        tp->procedure(tp->p)                         '用戶線程執行的過程(任何Ptr)
        MutexUnlock(tp->sync)                        'Mutex(解鎖)用戶線程
        Sleep 5
    Loop Until tp->quit = tp->true                   '測試結束用戶線程
End Sub

'-----------------------------------------------------------------------------------------------------

Type Point2D
    Dim x As Integer
    Dim y As Integer
End Type

Const x0 As Integer = 640 / 2
Const y0 As Integer = 480 / 2
Const r0 As Integer = 200
Const pi As Single = 4 * Atn(1)

Sub PointOnCircle (ByVal p As Any Ptr)
    Dim pp As Point2D Ptr = p
    Dim teta As Single = 2 * pi * Rnd
    pp->x = x0 + r0 * Cos(teta)
    Sleep 5                            '增加不相關的數據發生的可能性
    pp->y = y0 + r0 * Sin(teta)
End Sub


Screen 12
Locate 30, 2
Print "<any_key >:exit";

Dim Pptr As Point2D Ptr = New Point2D
Pptr->x = x0 + r0 * Cos(0)
pptr->y = y0 + r0 * Sin(0)

Dim Tptr As ThreadUDT Ptr = New ThreadUDT
Tptr->sync = MutexCreate
Tptr->procedure = @PointOnCircle
Tptr->p = Pptr
Tptr->handle = ThreadCreate(@ThreadUDT.Thread, Tptr)

Do
    MutexLock(Tptr->sync)   '用于主線程的互斥(鎖定)
    PSet (Pptr->x, Pptr->y)
    MutexUnlock(Tptr->sync) 'Mutex(解鎖)主線程
    Sleep 5
Loop Until Inkey <> ""
 
Tptr->quit = Tptr->true
ThreadWait(Tptr->handle)
MutexDestroy(Tptr->sync)
Delete Tptr
Delete Pptr

非有必要,多個線程還是不要用全局變量為好,因為那樣,老是在互相等待中,失去了多線程的同時運行的意義。

因國家互聯網安全管理要求,關閉回帖功能。大家需要留言,請使用【勇芳軟件客服】即時聯系勇芳點此打開->>勇芳軟件客服
返回
聯系勇芳
一个人看的www视频播放中文_2012中文字幕电影_亚洲国产成人高清在线观看_中文字幕天堂最新版在线网