分享

VB.net学习笔记(二十九)认识STA与MTA

 龙门过客栈 2017-11-17


一、应用程序中的多线程
    VB5/6支持多线程,但支持的线程模式都是STA(单线程单元,Single Threaded Apartments)。

    .NET Framework中没有单元的概念,它是在应用程序域中管理所有线程的。默认情况下,所有的.NET应用程序都是多线程的,它们可以在任一时间访问所有的对象。故关注托管代码中的共享资源是值得的。

    .NET Framework支持托管的和非托管的线程,并支持所有的Win32线程模式。当您试图从托管代码屮访问COM组件时,传统的COM组件将创建非托管线程。.NET Framework中的线程,无论是托管的还是非托管的,都是使用Thread对象创建的。

   Win32时的界面线程(UIT,User-Interface Threads)与用户线程(Worker Threads),现在被叫作单元模式线程(AMT,Apartment Model Threading)与自由线程(FT,Free Threading)。.net中还被称作单线程单元(STA,Single Threaded Apartment)或多线程单元(MTA,Multi Threaded Apartment)。

二、STA线程模式
    STA线程单元的运行方式称为每客户对象模式(Object-per-Client),即创建STA线程单元的代码拥有它自己的线程,在任何一个单元之内都只能有个线程。
                               
    (单元(Apartment)是一个逻辑容器,在相同上下文为共享线程的应用程序域内。进程激活后,创建的对象也将驻留在应用程序域,与之对应的上下文也被创建。)

    在STA中,对线程的所有调用都将被放置到一个队列中,然后逐个地处理对线程的调用。因此,STA线程永远不会同时执行多个方法。STA线程有自己的专有数据,它们不会在线程之间共享数据。这种特征使这一线程模式非常安全,避免了数据的损坏和同步问题。然而,这种特征也束缚了开发人员的手脚,产生了一定的性能损害,因为每当创建一个线程时,都要进行数据副本工作。

    线程亲合性用于定义线程和创建线程的代码之间的关系。每当调用STA单元线程时,调用者和线程之间的调用将由AppDomain之中的上下文进行处理,并由上下文维持线程的亲和性。

    如果要特别指定使用单元线程模式的话,使用Main()方法上的STAThreadAttribute属性即可实现这一操作。(VS2015已经将STAThreadAttribute改写为STAThread)

  1. <STAThread> Sub Main()  
  2.     '.....  
  3. End Sub  
  4.   
  5.   
  6. <MTAThread> Sub Main() ‘默认多线程,可不写  
  7.     '.....  
  8. Sub  

三、MTA线程模式
    STA和MTA线程单元的最大不同在于,在相同的MTA单元中可以同时容纳多个正在运行的线程,这些线程使用在单元中可用的所有共享数据。
                      

    1、如何设计线程
    首先明确,在单核中同一时刻只有一个进程获得CPU。

                    

    并发在单核和多核都可存在,就是同一时间有多个可以执行的进程。并行是指同一时间多个进程在微观上都在真正的执行,这就只有在多核的情况下了。

    拥有两个或以上的多线程程序,无论是否使用并行,只要是并发就会显著提升性能。

    并发线程执行意味着在同时间内有两个或更多个线程处于运行之中。线程并行则是两个或以上线程分别在不同的处理处理器上同时执行(上图)。

     在开发应用程序之前,应该考虑下列问题:
         (1)应用程序是否需要专门分出线程来处理?
         (2)若需要线程,怎么分,分出的准则是什么?
         (3)主线程和工作者线程之间如何协调、如何控制?

    2、线程间的关系
    多线程应用程序中生成的线程之间可能存在关系,也可能不存在关系。它们主有三种情况:主线程和工作者线程模式、对等线程模式、管道线程模式。   

       (1)主线程和工作者线程模式
        这是最常见的模式。主线程接收所有的输入,并将这些输入传递给其他线程来执行某些任务。主线程需要等待工作者线程的结束,也可能不需要。在这种模式中,工作者线程不和输入源发生交互作用,它们是从主线程中读取数据来执行任务的。线程是完全相互独立的,所有的线程完全受控于其父线程。
              

      (2)对等线程模式
      此模式下,每个线程都将从适当的来源接收其自己的输入,并对输入作出相应的处理。例如,UI线程将从键盘和鼠标处接收输入,并进行相应的处理。另一方面,Worker线程A将监听特殊的套接字Socket,当发现有从套接字传递过来的输入信息时就作出相应的处理。同样,Worker线程B将等待系统事件,并作出相应的处理。在这种模式中,所有的线程都将并行执行,不会产生阻塞和等待其他线程的情况。
                    

      (3)管道线程模式
        管道线程模式是基于一系列任务的,并且每个任务都依赖于前面的任务。例如,主线程创建了一系列线程,在前面的线程执行完毕之前,其他的所有线程都将等待。如果您的任务分成若干个阶段,每个阶段都依赖于前一阶段任务,那么这种类型的线程关系将显示出其独特的优点。
                      

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多