VB.NET并行与分布式编程(6)-线程与内核同步[12]
程序员文章站
2022-04-29 10:55:20
...
我们还可以使用信号量来完成同步
Semaphore 类限制可同时访问某一资源或资源池的线程数,即信号量。
线程通常使用 WaitOne 方法进入信号量,并且通常使用此方法重载以退出
WaitOne 方法阻止当前线程,直到当前 WaitHandle 收到信号为止,即增加减少一个信号量
Semaphore.Release 方法退出信号量并返回前一个计数,增加一个信号量。 我们先实现一个简单的信号量,1个生产线程和3个消费线程完成输出一行提示的工作,然后共同操作一个信号量 代码如下:
Imports System Imports System.Threading Imports System.Diagnostics Imports System.Diagnostics.ThreadState Module Module1 Sub Main() Dim mythread1 As Thread Dim mythread2 As Thread Dim mythread3 As Thread Dim mymakethread As Thread '创建线程对象 mythread1 = New Thread(AddressOf mythreadrun) mythread2 = New Thread(AddressOf mythreadrun) mythread3 = New Thread(AddressOf mythreadrun) mymakethread = New Thread(AddressOf mymake) Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程") '定义一个信号量 Dim mysemaphore As New Semaphore(0, 5) '执行线程 mymakethread.Start(mysemaphore) mythread1.Start(mysemaphore) mythread2.Start(mysemaphore) mythread3.Start(mysemaphore) '等待线程完成 mymakethread.Join() mythread1.Join() mythread2.Join() mythread3.Join() '线程执行完毕 Console.WriteLine(Now.ToLongTimeString & "主线程执行完毕!") mysemaphore.Close() End Sub Public Sub mymake(ByVal semaphore As Semaphore) '生产者线程 Dim i As Integer Dim mycount As Integer '生产者完成生产5次就退出生产者线程,这里假定就输出一行 For i = 1 To 5 Console.WriteLine("{0}号生产者线程等待运行", Thread.CurrentThread.ManagedThreadId) '增加1个信号量,并返回调用Release之前的信号量 mycount = semaphore.Release() Console.WriteLine("{0}号生产者线程运行,上次线号量为:{1}", Thread.CurrentThread.ManagedThreadId, mycount) Thread.Sleep(1) Next End Sub Public Sub mythreadrun(ByVal semaphore As Semaphore) '消费者线程,这里假定就输出一行 Try Console.WriteLine("{0}号消费者线程等待运行", Thread.CurrentThread.ManagedThreadId) '将信号量的计数减1,如果此时信号量为0,则等待 semaphore.WaitOne() Console.WriteLine("{0}号消费者线程运行", Thread.CurrentThread.ManagedThreadId) Thread.Sleep(15) Catch Console.WriteLine("{0},{1}号线程异常终止!", Now.ToLongTimeString, Thread.CurrentThread.ManagedThreadId) '终止线程 Thread.CurrentThread.Abort() Finally Console.WriteLine("{0},{1}消费者线程运行完成!", Now.ToLongTimeString, Thread.CurrentThread.ManagedThreadId) End Try End Sub End Module
上述代码有几个地方需要注意:
1、信号量的增加
Release()方法释放信号量,实质是增加一个信号量
Release()方法可以带参数,其参数可以指定增加几个信号量
2、信号量关闭
用完信号量后,需要关闭,close()
3、信号量的减少
WaitOne()方法实现等待信号量,如果还有信号量可以供使用,则减1
4、信号量对象的初始化
Dim mysemaphore As New Semaphore(0, 5)
0为初始值,5为最大值