欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

VB.NET并行与分布式编程(6)-线程与内核同步[2]

程序员文章站 2022-04-29 15:21:30
...

那么我们通过关键区域可以解决这个问题吗

Thread.BeginCriticalRegion 通知宿主执行将要进入一个代码区域,在该代码区域内线程中止或未经处理的异常的影响可能会危害应用程序域中的其他任务。公共语言运行时 (CLR) 的宿主(如 Microsoft SQL Server 2005)可以对关键和非关键代码区域建立不同的失败策略。 关键区域是指线程中止或未经处理的异常的影响可能不限于当前任务的区域。 相反,非关键代码区域中的中止或失败只对出现错误的任务有影响。

我们将减法部分与输出计算结果部分纳入关键区域

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





        '创建线程对象
        mythread1 = New Thread(AddressOf mythreadrun)
        mythread2 = New Thread(AddressOf mythreadrun)
        mythread3 = New Thread(AddressOf mythreadrun)
        mythread1.Name = "thread_1"
        mythread2.Name = "thread_2"
        mythread3.Name = "thread_3"
        '设置线程是否允许动态优先级








        Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程")
        Dim myprocess As Process = Process.GetCurrentProcess()
        Console.WriteLine("进程名称:" & myprocess.ProcessName)
        '执行线程
        mythread1.Start(myprocess)
        mythread2.Start(myprocess)
        mythread3.Start(myprocess)





        '等待线程完成
        mythread1.Join()
        mythread2.Join()
        mythread3.Join()


        '线程执行完毕
        Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!")

    End Sub
    Public Sub mythreadrun(ByVal myprocess As Object)
        Dim mynum As Double


        Static Dim jg As Double = 100
        Try
            For mynum = 1 To 2 Step 0.1
                Thread.BeginCriticalRegion()
                jg -= mynum
                Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>" & (jg + mynum) & "-" & mynum & ",计算结果为:" & jg)
                Thread.EndCriticalRegion()
            Next
        Catch
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程异常终止!")
            '终止线程
            Thread.CurrentThread.Abort()
        Finally
            Console.WriteLine(Thread.CurrentThread.Name & "优先级:  " & Thread.CurrentThread.Priority.ToString)
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程运行完毕!")
        End Try
    End Sub
End Module

 

 

结果证明没有效果,单纯的关键区域(临界域)解决不了这种数据同步问题

 
 

 


VB.NET并行与分布式编程(6)-线程与内核同步[2]
            
    
    博客分类: .net&silverlight  
 其关健在于要解决对数据本身锁的问题,由此我们引入互斥体,互斥体是一个仅用于实现同步的内核对象,目的是构建拥有互斥行为的临界域(即前面所说的关键区域)

 

 

 

 

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





        '创建线程对象
        mythread1 = New Thread(AddressOf mythreadrun)
        mythread2 = New Thread(AddressOf mythreadrun)
        mythread3 = New Thread(AddressOf mythreadrun)
        mythread1.Name = "thread_1"
        mythread2.Name = "thread_2"
        mythread3.Name = "thread_3"
        '设置线程是否允许动态优先级








        Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程")
        Dim myprocess As Process = Process.GetCurrentProcess()
        Console.WriteLine("进程名称:" & myprocess.ProcessName)
        '执行线程
        mythread1.Start(myprocess)
        mythread2.Start(myprocess)
        mythread3.Start(myprocess)





        '等待线程完成
        mythread1.Join()
        mythread2.Join()
        mythread3.Join()


        '线程执行完毕
        Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!")

    End Sub
    Public Sub mythreadrun(ByVal myprocess As Object)
        Dim mynum As Double
        Static Dim mymutex As New Mutex


        Static Dim jg As Double = 100
        Try
            For mynum = 1 To 10
                Thread.BeginCriticalRegion()
                mymutex.WaitOne()
                jg -= mynum
                Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>" & (jg + mynum) & "-" & mynum & ",计算结果为:" & jg)
                Thread.EndCriticalRegion()
                Thread.Sleep(0)
                mymutex.ReleaseMutex()
            Next
        Catch
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程异常终止!")
            '终止线程
            Thread.CurrentThread.Abort()
        Finally
            'mymutex.Close()
            Console.WriteLine(Thread.CurrentThread.Name & "优先级:  " & Thread.CurrentThread.Priority.ToString)
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程运行完毕!")
        End Try
    End Sub
End Module

 上述代码的重点在于:

首先在工作线程中,声明一个静态互斥体,这样多个线程可以共享一个互斥体

        Static Dim mymutex As New Mutex

然后,通过  Mutex.WaitOne()方法等待互斥体被释放,使用完变量jg后,释放互斥体,允许其它线程对jg进行操作

        Try
            For mynum = 1 To 10
                Thread.BeginCriticalRegion()
                mymutex.WaitOne()
                jg -= mynum
                Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>" & (jg + mynum) & "-" & mynum & ",计算结果为:" & jg)
                Thread.EndCriticalRegion()
                Thread.Sleep(0)
                mymutex.ReleaseMutex()

 

可以看到通过引入互斥体,同步问题得到了解决

 


VB.NET并行与分布式编程(6)-线程与内核同步[2]
            
    
    博客分类: .net&silverlight  

  • VB.NET并行与分布式编程(6)-线程与内核同步[2]
            
    
    博客分类: .net&silverlight  
  • 大小: 29.3 KB
  • VB.NET并行与分布式编程(6)-线程与内核同步[2]
            
    
    博客分类: .net&silverlight  
  • 大小: 48.2 KB