找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3341|回复: 4

【VFB】多线程(VFB教程3-3)

[复制链接]
发表于 2018-2-26 22:48:24 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
此处为VisualFreeBasic编程教程(从零开始学或VB进阶)的子章节部分,全部目录点链接。
使用多线程非常简单,就如同调用本地过程一样
  1. ThreadDetach ThreadCreate(@abc,0) '经典调用方法 -------------------------------------------------
  2. sub abc(aa as long)  '线程标准写法 .....
  3. end sub
复制代码

ThreadCreate 创建线程,会返回线程句柄
只可以传1个参数给线程,线程句柄不用后,必须释放,就用 ThreadDetach ,只是释放句柄,但不会终止线程
有个 ThreadWait 是等待线程完成,才执行下一行,除非特殊情况,不然失去了多线程的意义,很少用到。
还有个种方法创建线程,可以带多个参数
  1. ''线程使用“ThreadCall”

  2. Sub thread( id As String, tlock As Any Ptr, count As Integer )
  3.     For i As Integer = 1 To count
  4.         MutexLock tlock
  5.         Print "线" & id;
  6.         Locate , 20
  7.         Print i & "/" & count
  8.         MutexUnlock tlock
  9.     Next
  10. End Sub

  11. Dim tlock As Any Ptr = MutexCreate()
  12. Dim a As Any Ptr = ThreadCall thread("A", tlock, 6)
  13. Dim b As Any Ptr = ThreadCall thread("B", tlock, 4)
  14. ThreadWait a
  15. ThreadWait b
  16. MutexDestroy tlock
  17. Print "全部完成(并且没有Dim Shared!)"
复制代码
使用Threadcall是创建线程的更简单的方法,并允许将数据传递到线程,而不会有全局变量或不是类型安全的指针。但是,ThreadCreate更有效率,应该用于创建大量线程的程序。
  1. Function IsThreadAlive(ByVal dwThread As HANDLE ) As BOOL
  2. '判断线程句柄是否被终止 , 如果终止返回FALSE,如果还活着返回TRUE
  3.     Dim bRet As BOOL ,ExitCode As Ulong
  4.         If GetExitCodeThread(dwThread,@ExitCode) Then
  5.             If ExitCode = STILL_ACTIVE Then bRet = True
  6.         End If
  7.     Return bRet
  8. End Function
  9. ’此函数已经在VFB函数库里,不需要自己创建,直接调用
复制代码
有时需要知道,线程是不是活着还是终止,就用以上函数
  1. Dim cc As HANDLE Ptr '线程指针
  2. cc= ThreadCreate(@abc,0) '经典调用方法
  3. If  IsThreadAlive(*cc) Then  '*CC 取出的是线程句柄
  4. End If
  5. Threaddetach cc '释放线程句柄
  6. -------------------------------------------------
  7. sub abc(aa as long)  '线程标准写法
  8. .....
  9. end sub
复制代码

假如,有多个线程使用的全局变量,那么,就可能发生问题了,1个读1个写。

(如果是单个数字变量,可以不用考虑,字符串、数组等,肯定出问题)
MutexCreate创建个互斥体来,读写全局变量时用MutexLock锁定,过后用MutexUnlock解锁。
  1. '使用Mutex进行线程同步的可视示例:
  2. '“用户定义的线程”计算圆上的点坐标,
  3. '和“主线程”绘制点数。
  4. '
  5. '如果你注释掉包含“MutexLock”和“MutexUnlock”的行
  6. '(在“用户定义的线程”或/和“主线程”内),
  7. '两个线程(“用户定义”和“主”)将不会同步,
  8. '并且许多点不会在圆上绘制(由于非相干坐标)。

  9. '-----------------------------------------------------------------------------------------------------

  10. Type ThreadUDT                                   '通用用户线程UDT
  11.     Dim handle As Any Ptr                        '任何用户线程的Ptr句柄
  12.     Dim sync As Any Ptr                          '互斥体的任何Ptr句柄
  13.     Dim quit As Byte                             '布尔到最终用户线程
  14.     Declare Static Sub Thread (ByVal As Any Ptr) '通用用户线程程序
  15.     Dim procedure As Sub (ByVal As Any Ptr)      '用户线程执行的过程(任何Ptr)
  16.     Dim p As Any Ptr                             '任何Ptr传递给用户线程执行的过程
  17.     Const false As Byte = 0                      '常数“假”
  18.     Const true As Byte = Not False               '康斯坦丁“真”
  19. End Type

  20. Static Sub ThreadUDT.Thread (ByVal param As Any Ptr) '通用用户线程程序
  21.     Dim tp As ThreadUDT Ptr = param                  '转换为通用用户线程UDT
  22.     Do
  23.         MutexLock(tp->sync)                          '互斥(锁定)用户线程
  24.         tp->procedure(tp->p)                         '用户线程执行的过程(任何Ptr)
  25.         MutexUnlock(tp->sync)                        'Mutex(解锁)用户线程
  26.         Sleep 5
  27.     Loop Until tp->quit = tp->true                   '测试结束用户线程
  28. End Sub

  29. '-----------------------------------------------------------------------------------------------------

  30. Type Point2D
  31.     Dim x As Integer
  32.     Dim y As Integer
  33. End Type

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

  38. Sub PointOnCircle (ByVal p As Any Ptr)
  39.     Dim pp As Point2D Ptr = p
  40.     Dim teta As Single = 2 * pi * Rnd
  41.     pp->x = x0 + r0 * Cos(teta)
  42.     Sleep 5                            '增加不相关的数据发生的可能性
  43.     pp->y = y0 + r0 * Sin(teta)
  44. End Sub


  45. Screen 12
  46. Locate 30, 2
  47. Print "<any_key >:exit";

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

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

  56. Do
  57.     MutexLock(Tptr->sync)   '用于主线程的互斥(锁定)
  58.     PSet (Pptr->x, Pptr->y)
  59.     MutexUnlock(Tptr->sync) 'Mutex(解锁)主线程
  60.     Sleep 5
  61. Loop Until Inkey <> ""

  62. Tptr->quit = Tptr->true
  63. ThreadWait(Tptr->handle)
  64. MutexDestroy(Tptr->sync)
  65. Delete Tptr
  66. Delete Pptr
复制代码

非有必要,多个线程还是不要用全局变量为好,因为那样,老是在互相等待中,失去了多线程的同时运行的意义。

回复

使用道具 举报

发表于 2020-2-18 09:08:56 | 显示全部楼层
能力有限  看不懂!
回复 赞! 靠!

使用道具 举报

发表于 2022-5-13 16:56:55 | 显示全部楼层

论坛有你真的精彩~
回复 赞! 靠!

使用道具 举报

发表于 2023-4-20 00:10:41 | 显示全部楼层
没有研究过~~~
回复 赞! 靠!

使用道具 举报

发表于 2023-4-22 20:54:52 | 显示全部楼层
我看到你有互斥锁,那么更底层的原子操作应该也有吧?原子操作的代码也展示一下不
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-21 23:41 , Processed in 0.034420 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表