zoukankan      html  css  js  c++  java
  • 第二十七章 计算限制的异步操作

    目录

    27.1 CLR线程池基础

    27.2 执行简单的计算限制操作

    27.3 执行上下文

    27.4 协作式取消和超时

    27.5 任务

    27.6 Parallel的静态For,ForEach和Invoke方法

    27.7 并行语言集成查询(PLINQ)

    27.8 执行定时计算限制操作

    27.9 线程池如何管理线程

    异步执行计算限制操作,允许线程池在多个CPU内核上调度任务,使多个线程能并发工作,从而高效率地使用系统资源,同时提升应用程序的吞吐能力。

    27.1 CLR线程池基础

    线程池是你的应用程序能使用的线程集合。每CLR一个线程池:这个线程池由CLR控制的所有AppDomain共享。

    CLR初始化时,线程池中是没有线程的。在内部,线程池维护了一个操作请求队列。应用程序执行一个异步操作时,就调用某个方法,将一个记录项追加到线程池队列中。线程池的代码从这个队列中提取记录项,将这个记录项派发给一个线程池线程。

    27.2 执行简单的计算限制操作

    将一个异步的计算限制操作放到线程池队列中:ThreadPool类

    static Boolean QueueUserWorkItem(WaitCallback callback);

    static Boolean QueueUserWorkItem(WaitCallback callback, Object state); 

    27.3 执行上下文

    每个线程都关联了一个执行上下文数据结构。执行上下文包括的东西有安全设置(压缩栈,Thread的Principal属性和Winodws身份)、宿主设置以及逻辑调用上下文数据。

    ExecutionContext类:

    [SecurityCritical] public static AsyncFlowControl SuppressFlow();

    public static void RestoreFlow();

    public static Boolean IsFlowSuppressed();

    27.4 协作式取消和超时

     Microsoft .NET Framework 提供了标准的取消操作模式。这个模式是协作式的,意味着要取消的操作必须显示支持取消。

    System.Threading.CancellationTokenSoure包含了和管理取消有光的所有状态。

    public struct CancellationToken:

    CancellationToken 实例是轻量级值类型,包含单个私有字段,即对其CancellationToken的IsCancellationRequested属性,了解循环是否应该提前终止,从而终止计算限制的操作。

    27.5 任务

    System.Threading.Tasks命名空间

    27.5.1 等待任务完成并获取结果

    如果计算限制的任务抛出未处理的异常,异常会被“吞噬”并存储到一个集合中,而线程池线程可以返回到线程池中。调用Wait方法或者Result属性时,这些成员会抛出一个System.AggregateException对象

    27.5.2 取消任务

    可调用一个CancellationTokenSource取消Task。

    27.5.3 任务完成时自动启动新任务

    伸缩性好的软件不应该使线程阻塞

    27.5.4 任务可以启动子任务

    任务支持父/子关系。

    27.5.5 任务内部揭秘

    每个Task对象都有一组字段,这些字段构成了任务的状态。其中包括一个Int32ID,代表Task执行状态的一个Int32,对父任务的引用,对Task创建时指定的TaskScheduler的引用,对回调方法的引用,对要传给回调方法的对象的引用,对ExecutionContext的引用以及对MenualResetEventSlim对象的引用。另外,每个Task对象都有对根据需要创建的补充状态的引用。补充状态包含了一个CancellationToken,一个ContinueWithTask对象集合,为抛出未处理异常的子任务而准备的一个Task对象集合等。

    首次构造Task对象时,它的状态时Created。以后,当任务启动时,它的状态变成WaitingToRun。Task实际在一个线程上运行时,它的状态变成Runing。任务停止运行,并等待它的任何子任务时,状态变成WaitingForChildrenToComplete。任务完成时进入以下状态之一:RanToCompletion(运行完成),Canceld(取消)或Faulted(出错)。

    27.5.6 任务工厂

    TaskFactory

    27.5.7 任务调度器

    TaskScheduler对象负责执行被调度的任务,同时向Visual Studio调试器公开任务信息。FCL提供了两个派生自TaskScheduler的类型:线程池任务调度器,和同步上下文任务调度器。任务调度器将任务调度给线程池的工作者线程。

    27.6 Parallel的静态For,ForEach和Invoke方法

    System.Threading.Tasks.Parallel:For,ForEach,Invoke

    Parallel的所有方法都让调用线程参与处理。调用Parallel方法的前提是:工作项必须能并行执行。另外,要避免会修改任何共享数据的工作项,否则多个线程同时处理可能会损坏数据。

    重载版本:

    接受ParallelOptions对象:

    CancellationToke:允许取消操作。

    Int32MaxDegreeOfParallelism:允许指定可以并发操作的最大工作项目数。

    TaskSchedulerTaskScheduler:允许指定要使用哪个TaskScheduler。

    任务局部初始化委托:为参与工作的每个任务都调用一次该委托。这个委托是在任务别要求处理一个工作项之前调用的。

    主体委托:为参与工作的各个线程所处理的每一项都调用一次该委托。

    任务局部终结委托:为参与工作的每一个任务都调用一次该委托。这个委托是在任务处理好派发给它的所有工作项之后调用。即使主体委托代码引发一个未处理的异常,也会调用它。

    27.7 并行语言集成查询(PLINQ)

     使用LINQ to Objects时,只有一个线程顺序处理数据集合中的所有项:我们称之为顺序查询。要提高处理性能,可以使用并行LINQ(parallel LINQ),它将顺序查询转换成并行查询,在内部使用任务,将集合中的数据项的处理工作分散到多个CPU上,以便并发处理多个数据项。

    AsParallel;AsSequential

    27.8 执行定时计算限制操作

     System.Threading命名空间定义了一个Timer类,可用它让一个线程池线程定时调用一个方法。

    System.Threading的Timer类:要在一个线程池线程上执行定时的(周期性发生的)后台任务,它是最好的计时器。

    System.Windows.Forms的Timer类:构造这个类的实例,相当于告诉Windows将一个计时器和调用线程关联。

    System.Windows.Threading的DispatcherTimer类:这个类是System.Windows.Forms的Timer类在Silverlight和WPF应用程序中的等价物。

    Windows.UI.Xaml的DispatcherTimer类:这个类是System.Windows.Forms的Timer类在Windows Store应用中的等价物。

    System.Timers的Timer类:这个计时器本质上是System.Threading的Timer类包装器。计时器到期(触发)会导致CLR将事件放到线程池队列中。(不建议使用)

    27.9 线程池如何管理线程

    27.9.1 设置线程池限制

    CLR允许开发人员设置线程池要创建的最大线程数。但实践证明,线程池永远都不应该设置线程数上限,因为可能发生饥饿或死锁。

    27.9.2 如何管理工作者线程

    ThreadPool.QueueUserWorkItem方法和TImer类总是将工作项放到全局队列中。工作者线程采用一个先入先出(FIFO)算法将工作项从这个队列中取出,并处理它们。由于多个工作者线程可能同时从全局队列中拿走工作项,所以所有工作者线程都竞争一个线程同步锁,以保证两个或多个线程不会获取同一个工作项。

    每个工作者线程都有自己的本地队列。工作者线程调度一个Task时,该Task被添加到调用线程的本地队列。非工作者线程调度一个Task时,该Task被添加到全局队列。工作者线程采用后入先出(LIFO)算法将任务从本地队列中取出。由于工作者线程是唯一允许访问它自己的本地队列头的线程,所以无需同步锁,而且在队列中添加和删除Task的速度非常快,

    每天学习一丢丢
  • 相关阅读:
    cpu capacity、task_util、cpu_util是如何计算的?
    QTI EAS学习之find_energy_efficient_cpu
    Linux内核进程调度overview(1)
    Ondemand和Interactive gonernor工作逻辑简述
    利用init进程监控底层节点的方法架构
    Sched_Boost小结
    SchedTune
    Cpusets学习
    搭建SpringCloud微服务框架:三、读取Nacos的配置信息
    搭建SpringCloud微服务框架:一、结构和各个组件
  • 原文地址:https://www.cnblogs.com/terry-1/p/11111760.html
Copyright © 2011-2022 走看看