数学之路-vb.net并行计算(5)

一、线程状态涉及的CLR类

1)Process 类

提供对本地和远程进程的访问并使您能够启动和停止本地系统进程

 

GetCurrentProcess  获取新的 Process 组件并将其与当前活动的进程关联。

 

2)ProcessThread 类

使用 ProcessThread 来获取系统上当前运行的线程的信息。 例如,这样做将使您能够监视线程的性能特性。

线程是沿程序执行的路径。 它是 Win32 安排的最小执行单位。 它由堆栈、CPU 注册的状态和系统计划程序的执行列表中的项组成。

进程包括一个或多个线程和代码、数据和内存中的其他程序资源。 典型的程序资源是打开的文件、信号灯和动态分配的内存。 进程的所有线程共享该进程的每一资源。

当系统计划程序给程序的线程之一执行控制权时,程序便执行。 计划程序确定哪些线程运行以及何时运行。 在较高优先级的线程完成任务的时候,较低优先级的线程可能会被迫等待。 在多处理器计算机上,计划程序可将单个线程移到不同的处理器上,从而对 CPU 负荷进行平衡。

每个进程启动时都具有一个线程,该线程称为主线程。 任何线程都可以创建附加线程。 进程中的所有线程共享该进程的地址空间。

常用方法如下:

  BasePriority  获取线程的基本优先级。  
  CanRaiseEvents  获取一个指示组件是否可以引发事件的值。 (继承自 Component。) 
  Container  获取 IContainer,它包含 Component。 (继承自 Component。) 
  CurrentPriority  获取线程的当前优先级。  
  DesignMode  获取一个值,用以指示 Component 当前是否处于设计模式。 (继承自 Component。) 
  Events  获取附加到此 Component 的事件处理程序的列表。 (继承自 Component。) 
  Id  获取线程的唯一标识符。  
  IdealProcessor  设置让此线程在其上运行的首选处理器。  
  PriorityBoostEnabled  获取或设置一个值,该值指示每当关联线程的进程主窗口接收焦点时,操作系统是否暂时提升该线程的优先级。  
  PriorityLevel  获取或设置线程的优先级别。  
  PrivilegedProcessorTime  获取线程在操作系统内核中运行代码所用的时间。  
  ProcessorAffinity  设置关联线程可以在其上运行的处理器。  
  Site  获取或设置 Component 的 ISite。 (继承自 Component。) 
  StartAddress  获取操作系统调用的、启动此线程的函数的内存地址。  
  StartTime  获取操作系统启动该线程的时间。  
  ThreadState  获取此线程的当前状态。  
  TotalProcessorTime  获取此线程使用处理器的时间总量。  
  UserProcessorTime  获取关联的线程在应用程序内运行代码所用的时间。  
  WaitReason  获取线程等待的原因。

 

属性为:

 BasePriority  获取线程的基本优先级。  
  CanRaiseEvents  获取一个指示组件是否可以引发事件的值。 (继承自 Component。) 
  Container  获取 IContainer,它包含 Component。 (继承自 Component。) 
  CurrentPriority  获取线程的当前优先级。  
  DesignMode  获取一个值,用以指示 Component 当前是否处于设计模式。 (继承自 Component。) 
  Events  获取附加到此 Component 的事件处理程序的列表。 (继承自 Component。) 
  Id  获取线程的唯一标识符。  
  IdealProcessor  设置让此线程在其上运行的首选处理器。  
  PriorityBoostEnabled  获取或设置一个值,该值指示每当关联线程的进程主窗口接收焦点时,操作系统是否暂时提升该线程的优先级。  
  PriorityLevel  获取或设置线程的优先级别。  
  PrivilegedProcessorTime  获取线程在操作系统内核中运行代码所用的时间。  
  ProcessorAffinity  设置关联线程可以在其上运行的处理器。  
  Site  获取或设置 Component 的 ISite。 (继承自 Component。) 
  StartAddress  获取操作系统调用的、启动此线程的函数的内存地址。  
  StartTime  获取操作系统启动该线程的时间。  
  ThreadState  获取此线程的当前状态。  
  TotalProcessorTime  获取此线程使用处理器的时间总量。  
  UserProcessorTime  获取关联的线程在应用程序内运行代码所用的时间。  
  WaitReason  获取线程等待的原因。 

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)
        Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程")


        ‘执行线程
        mythread1.Start("线程1")
        mythread2.Start("线程2")
        mythread3.Start("线程3")





本博客所有内容是原创,如果转载请注明来源

http://blog.csdn.net/myhaspl/




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




        ‘线程执行完毕
        Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!")
    End Sub
    Public Sub mythreadrun(ByVal data As Object)
        Dim mynum As Integer








        ‘GetCurrentProcess  获取新的 Process 组件并将其与当前活动的进程关联。 






        ‘分配一个新的槽,这个槽存放线程本地数据,槽名称为
        ‘myjg,名称必须唯一
        Dim jg As LocalDataStoreSlot
        jg = Thread.GetNamedDataSlot("myjg")
        Thread.SetData(jg, 30)
        Try
            For mynum = 1 To 10
                Thread.SetData(jg, Thread.GetData(jg) - mynum)
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId & "==>" & Now.ToLongTimeString & "=>" & (Thread.GetData(jg) + mynum) & "-" & mynum & ",计算结果为:" & Thread.GetData(jg))
                ‘获取线程状态
                Thread.Sleep(5)
                Dim value As ProcessThreadCollection
                Dim pt As ProcessThread
                value = Process.GetCurrentProcess().Threads
                For Each pt In value
                    If pt.ThreadState = Wait Then
                        Console.WriteLine(pt.Id & "等待原因:" & pt.WaitReason.ToString)
                    End If
                Next
            Next
        Catch
            Console.WriteLine(data & "  " & Now.ToLongTimeString & "线程异常终止!")
            ‘终止线程
            Thread.CurrentThread.Abort()
        Finally
            Thread.FreeNamedDataSlot("myjg")
        End Try


    End Sub
End Module


4、运行效果

 


技术分享
 

 对于等待原因来说,有以下几种:

我们需要使用ThreadWaitReason 枚举:

ThreadWaitReason 枚举

 

Executive  线程正在等待计划程序。  
 FreePage  线程正在等待可用的虚拟内存页。  
 PageIn  线程正在等待虚拟内存页到达内存。  
 SystemAllocation  线程正在等待系统分配。  
 ExecutionDelay  线程执行延迟。  
 Suspended  线程执行暂停。  
 UserRequest  线程正在等待用户请求。  
 EventPairHigh  线程正在等待事件对高。  
 EventPairLow  线程正在等待事件对低。  
 LpcReceive  线程正在等待本地过程调用到达。  
 LpcReply  线程正在等待对本地过程调用的回复到达。  
 VirtualMemory  线程正在等待系统分配虚拟内存。  
 PageOut  线程正在等待虚拟内存页写入磁盘。  
 Unknown  线程正在因未知原因而等待。 


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)
        Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程")


        ‘执行线程
        mythread1.Start("线程1")
        mythread2.Start("线程2")
        mythread3.Start("线程3")








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




        ‘线程执行完毕
        Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!")
    End Sub
    Public Sub mythreadrun(ByVal data As Object)
        Dim mynum As Integer














        ‘分配一个新的槽,这个槽存放线程本地数据,槽名称为
        ‘myjg,名称必须唯一
        Dim jg As LocalDataStoreSlot
        jg = Thread.GetNamedDataSlot("myjg")
        Thread.SetData(jg, 30)
        Try
            For mynum = 1 To 10
                Thread.SetData(jg, Thread.GetData(jg) - mynum)
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId & "==>" & Now.ToLongTimeString & "=>" & (Thread.GetData(jg) + mynum) & "-" & mynum & ",计算结果为:" & Thread.GetData(jg))
                ‘获取线程状态
                Thread.Sleep(5)
                Dim value As ProcessThreadCollection
                Dim pt As ProcessThread
                value = Process.GetCurrentProcess().Threads
                For Each pt In value
                    If pt.ThreadState = Wait Then
                        Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString)
                    Else
                        Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)
                    End If
                Next
            Next
        Catch
            Console.WriteLine(data & "  " & Now.ToLongTimeString & "线程异常终止!")
            ‘终止线程
            Thread.CurrentThread.Abort()
        Finally
            Thread.FreeNamedDataSlot("myjg")
        End Try


    End Sub
End Module


我们在上面代码中加入了线程状态的输出

Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)
在上一节和本节的上面代码中,与线程状态与调度有关的核心代码如下 :

                Dim value As ProcessThreadCollection
                Dim pt As ProcessThread
                value = Process.GetCurrentProcess().Threads
                For Each pt In value
                    If pt.ThreadState = Wait Then
                        Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString)
                    Else
                        Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)
                    End If
                Next
其中

1)得到当前进程的所有线程集合:

                value = Process.GetCurrentProcess().Threads

2)在线程集合中迭代

 For Each pt In value
.......

next

3)判断该线程的状态是不是等待

 If pt.ThreadState = Wait Then
4)等待原因

                        Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString)

 

注意pt.WaitReason和pt.ThreadState 都是枚举值,因此在前面


Imports System.Diagnostics.ThreadState

 

5)如果线程没有处于等待状态,则输出线程的当前状态

                        Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)

 6)pt.Id为获取线程的唯一标识符,ManagedThreadId 属性的值是一个整数,表示此托管线程的唯一标识符,不会随时间而变化,即使承载公共语言运行时的非托管代码将线程实现为纤程。

2、线程的名字可以使用Thread.Name ,它 是包含线程名称的字符串类型的 属性

我们把上面的代码改一下,加入thread.Name,不再像以前那样通过   mythread1.Start("线程1")
传入一个字符串参数进入线程,让线程内部知道它的名字


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 & "线程对象创建完毕,开始执行线程")


        ‘执行线程
        mythread1.Start()
        mythread2.Start()
        mythread3.Start()








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




        ‘线程执行完毕
        Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!")
    End Sub
    Public Sub mythreadrun()
        Dim mynum As Integer














        ‘分配一个新的槽,这个槽存放线程本地数据,槽名称为
        ‘myjg,名称必须唯一
        Dim jg As LocalDataStoreSlot
        jg = Thread.GetNamedDataSlot("myjg")
        Thread.SetData(jg, 30)
        Try
            For mynum = 1 To 10
                Thread.SetData(jg, Thread.GetData(jg) - mynum)
                Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>" & (Thread.GetData(jg) + mynum) & "-" & mynum & ",计算结果为:" & Thread.GetData(jg))
           Thread.Sleep(5)
            Next
        Catch
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程异常终止!")
            ‘终止线程
            Thread.CurrentThread.Abort()
        Finally
            Thread.FreeNamedDataSlot("myjg")
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程运行完毕!")
        End Try


    End Sub
End Module


注意以上代码的下面几个部分

1)

    Public Sub mythreadrun(ByVal myprocess As Object)

2)        Dim myprocess As Process = Process.GetCurrentProcess()
        Console.WriteLine("进程名称:" & myprocess.ProcessName)
        ‘执行线程
        mythread1.Start(myprocess)
        mythread2.Start(myprocess)
        mythread3.Start(myprocess)


 
技术分享



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。