C#并行编程高级教程:精通.NET 4 Parallel Extensions中文(第2部分)

所需积分/C币:10 2013-10-11 26.02MB pdf
评分

内容简介 您想淋漓尽致地发挥多核计算机系统的处理能力吗?《C#并行编程高级教程:精通NET 4 Parallel Extensions》将帮助您实现这一夙愿。这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合地使用高级Intel工具与C#,并指导您巧妙使用新引入的轻型协调结构来开发自己的解决方案并解决最棘手的并发编程问题。 主要内容 ◆介绍如何基于新Task Parallel Library和.NET
第5章协调数据结构 在这个示例中,这些字符串并不会像在前一个示例中那样根据时间排序。不过,您可 以在额外操作中完成排序。相比之前的版本,不带锁的新版本具有以下优点: 更为简单,因为不需要创建临界区,因此代码也更不容易出错。 更具可扩展性,因为没必要自旋等待获得锁,而且创建每一个字符串目志的代码 也不需要串行化 然而,这个不带锁的代码版本具有以下缺点: 需要消耗更多的内存,因为这段代码不是使用一个单独的 String Builder实例来创 建字符串目志,而是在每一个参与者中都使用了一个 String Builder实例,而且还 使用了一个汇总 String Builder实例来收集结果。 增加了从每一个任务采集结果并生成最终的字符串日志的额外开销。这个开销是 个串行操作产生的。 生成的字符串日志是无序的。如果您需要有序的日志,那么还需要添加一个排序 操作。 这个示例表明,在某些情况下,锁是可以避免的。为了选择最方便的替代 方案,您需要事先分析各种方案的优点和缺点。有时候,可以很方便地避免使 用锁;而在某些情况下,可能不允许无锁方案所带来的额外内存消耗和其他开 销。务必要记住的是,可以使用剖析功能来帮助您选择最方便的方案 在这个示例中,还有另外一种替换方案:您可以使用第4章介绍的新的并发集合来向 日志添加新的字符串。通过使用新的并发集合,可以省去需要添加显式同步的必要性,因 为这些新的并发集合已经准备好了应对并发地添加和删除元素。 55将自旋锁用作互斥锁原语 如果持有锁的时间总是非常短,而且锁的粒度很精细,那么自旋锁可以获得比其他锁 机制更好的性能。有时候,性能剖析和其他性能监测表明, Monitor互斥锁的开销非常大 在这种情况下,您可以对将 Monitor锁替换为自旋锁的结果进行测试。 下面的代码展示了程序清单5-1中所展示的Main方法第一部分的一个新版本。这个版 本的代码通过一个名为s的 SpinLock实例来获得一个锁,然后运行临界区内的代码,并 且在屏障的所有参与者内通过一个名为sb的 String Builder向日志字符串添加信息。这里将 Monitor获取锁和释放锁的方法替换为了 SpinLock实例及其方法。不过,这并不一定意味 着 SpinLock是替换 Monitor的更好的解决方案—这取决于不同的实际情况。事实上, String Builder要求内存分配,因此可能需要消耗未知的时间,因为潜在的分页操作可能会 消耗大量CPU周期。将 StringBuilder的 Append方法放在使用 Spin lock的临界区并不是一 个好方法。下面的代码展示了如何对代码进行修改,从而将 Monitor替换为 SpinLock 183 c#并行编程高级教程:精通NET4 Parallel Extensions static void Main(string[] args) 可从 tasks new Task[ participants]; Wrox com 下载源代码 barrier =new Barrier( participants, (barrier)=> Console. WriteLine("Current phase: 10]", barrier. Current PhaseNumber) }); // You pass false for enableThreadownerTracking // because you want the best performance out of SpinLock var sl new SpinLock(false)i var sb new stringBuilder()i for (int i=0;1< ticipants; i++) tasks[i]= Task. Factory. startNew((num)=> ar participantNumber =(int)numi f int 0;j<10;j++) CreatePlanets(participantNumber)i barrier. SignalAndWait()i Createstars (participantNumber)i barrier. SignalAndwait()i CheckcollisionsBetweenPlanets(participantNumber)i barrier. SignalAndwait()i CheckcollisionsBetweenStars(participantNumber)i barrier. signalAndwait(i RenderCollisions(participantNumber)i barrier. SignalAndwait()i var logline string. Format "Time:(0), Phase: (1), Participant: (21, Phase completed OK\n", DateTime. Now. TimeofDay, barrier. CurrentPhaseNumber, participantNumber)i bool lockTaken s false s1. Enter《xef1。 krAken); / SpinLock acquired a lock / Critical section sb. Append (logLine) / End of critical section finally / You need to make sure that /y。 u release the1ock 184 第5章协调数据结构 (1。 krAken) / Gives up the lock if it actually acquired it 7/ You want performance at the expense of fairness / Therefore, you pass false for useMemoryBarrier sl Exit(false)i },i); var finalTask Task Factory. ContinuewhenAll( tasks, (tasks)=> // Wait for all the tasks to ensure / the propagation of any exception occurred // in any of the tasks Task. WaitAll( tasks)i Console. Writeline "All the phases were executed. "); Console. WriteLine(sb)i //Dispose the Barrier instance barrier. Dispose()i }); / Wait for finalTask to finish finalTask, wait()i Console, Readline(i Snippet5-10中的代码片段 通过使用 SpinLock获得锁和释放锁的输出结果与之前通过使用 Monitor获得锁和释放 锁的输出结果是一致的。 String Builder实例sb的最终内容包含了所有参与者在临界区输出 的信息。 这段代码将 false作为参数传递给 SpinLock结构体的构造函数,并且将该实例存储在 sl局部变量中,这个局部变量可以被所有的参与者任务共享。 false值表示禁用作为调试目 的而使用的跟踪线程D的选项。如果您想要获得 SpinLock的最佳性能,那么可以像上面 这个示例一样将 false传递给构造函数。 SpinLock能够确保临界区将会串行执行,因此,在 SpinLock获得了一个互斥锁之后 也能安全地调用 Append方法。每一个参与者都将bool变量 lock Taken设置为 false,然后 调用 SpinLock实例s的 Enter方法,通过引用参数将 lock Taken传入。ty…, finally代码块 能够保证如果发生了错误,锁能够被释放。此时此刻, Enter方法将会试图获得锁,如果不 能获得锁,那么任务将会在一个循环内等待,并不断地检查锁是否变得可用。任务会一直自 旋,直到获得锁为止。一旦获得锁之后, lock Taken将会被设置为tue,并且∥ Critical section 这行代码后面的代码将会开始运行。如果此时有其他任务调用 Enter方法,则那些任务将 185 C#并行编程高级教程:精通NET4 Parallel Extensions 会开始自旋,直到运行临界区的任务调用 SpinLock实例sl的Ei方法将锁释放。因此, 确保这个方法一定会得到调用是一件非常重要的事情,即使在临界区内发生了异常也是如 此。 finally区域中的代码会检测 lockTaken是否设置为tue,从而确保具有在真正获得了锁 的时候才释放锁。当这一行代码执行之后,其他任务中的某一个任务就可以获得锁,并且 执行同样顺序的操作。为了迅速地将退出临界区的操作发布给其他线程,代码在调用Exit 方法的时候传入了 false参数,表示不用产生内存屏障( memory fence)。因为 SpinLock没有 使用内存屏障,所以可以通过牺牲公平性来获得性能提升。 bool lockTaken false try 可从 下载源代码 sl Enter(ref lockTaken); // SpinLock acquired a lock // Critical section sb. Append(logLine)i // End of critical section finally // You need to make sure that / you release the lock if(1。 krAken) / Gives up the lock if it actually acquired it // You want performance at the expense of fairness / Therefore, you pass false for useMemoryBarrier sl Exit(false)i Snippet5_11中的代码片段 不要将 SpinLock声明为只读字段,因为如果这么做的话,会导致每次调 用这个字段都返回 SpinLock的一个新副本,而不是原始的那个。所有对 Enter 方法的调用都能成功获得锁,因此受保护的临界区不会按照预期进行串行化。 551使用超时 与前面所介绍的 Monitor锁一样, SpinLock也提供了在指定的超时时间内获得锁的方 法。通过使用 SpinLock实例s的 TryEnter方法而不是 Enter方法可以建立超时。这个方法 有一种定义,可以在第1个参数中接受要等待的亳秒数,在第2个参数中接收一个bool变 量。与 Enter不同, TryEnter不会无限制地等待锁变得有效,而是会阻塞直到锁变得有效或 者指定的超时时间已经达到。因此,在调用 TryEnter之后,有必要检测bol变量的值,因 为 false值将表示因为超时而并没有获得锁。 下面的代码展示了一个新版本的代码,这段代码试图获得一个带有2000毫秒超时的 186 第5章协调数据结构 锁,然后运行临界区。调用 TryEnter方法的下一行代码会检查 lockTaken是否为 false,如 果为 false,则抛出一个 Timeout Exception异常。在这个示例中,异常并没有被捕捉到,因 此任务会出错退出并且停止执行。 bool lockTaken false tr y 可从 Hiro.on 下载源代码 sl. TrYEnter(2000, ref lockTaken)i i£(!1。 kraken / It was not possible to acquire the lock cons。e. Writeline《 Lock timeout for participant: 0)", participantNumber) row new TimeoutException string. Format( Participants are requiring more than [0] seconds w+ to acquire the lock at the Phase (11 2000, barrier. CurrentPhaseNumber)); / SpinLock acquired a lock // Critical section sb. Append(logLine) / End of critical section finally / You need to make sure that // you release the lock if (lockTaken) / Gives up the lock if it actually acquired it // SpinLock doesn't / You want performance at the expense of fairness / Therefore, you pass false for useMemoryBarrier sl Exit(false)i Snippet5_12中的代码片段 552使用基于自旋的等待 如果等待某个条件满足需要的时间很短,而且您不希望发生昂贵的上下文切换,那么 基于自旋的等待是一种很好的替换方案。 Spin Wait类型不仅提供了基本的自旋功能,而且 还提供了 SpinUntil)法,使用这个方法能够自旋直到满足某个条件为止。此外, Spin Wait 是一个 struct,而且只不过Int32大小,因此并不会产生不必要的内存分配的开销。从内存 使用的角度来说, Spin Wait的开销非常小 187 C并行编程高级教程:精通NET4 Parallel Extensions 长时间的自旋并不是很好的做法,因为自旋会阻塞更高优先级的线程及其相关的任 务,还会阻塞垃圾回收器。相反,如果自旋的时间过长, Spin Wai会让出底层线程的时间 片,并触发上下文切换。这种同步类型被设计为在大部分情况下提供正确的自旋行为,而 不会和简单的循环行为产生混淆。 Spin Wait还提供了一种智能的行为,能够判断何时停止 自旋并触发一次上下文切换。这种上下文切换开销很大,但是继续长时间自旋的开销更大。 Spin Wait通常会在自旋时间达到内核切换所需的时间时停止自旋。 SpinLock只不过是对 Spin Wait的简单包装 当一个线程自旋时,它会将一个内核放入到一个繁忙的循环中,而这不会让出当前处 理器时间片剩余的部分。然而,如前所述, Spin Wait结构中包含的智能逻辑会在自旋达到 足够长的时间时停止自旋并且让壯处理器。当一个任务或线程调用 Thread. Sleep方法的时 候,底层的线程可能会让出当前处理器时间片的剩余部分,这是一个大开销的操作。因此, 在大部分情祝下,不要在循环内调用 Thread. Sleep方法等待特定条件的满足。然而,需要 注意的特别重要的一点是,如果给 Thread. Sleep传入了0,那么当前线程会被挂起,从而允 许其他等待的线程开始执行 第4章介绍了 ConcurrentBag,并列举了一个小例,这个示例并发地加载了3个方法,分 别表示生产者和消费者。 Capitalize WordsIn Sentences既是 Producesentences的消费者,也是 RemoveLettersInSentences F生产者。 Capitalize WordsInSentences通过 Spint Wait. SpinUntil方 法等待共享的bol变量 producing Sententes变成tue之后才开始工作,如下所示 private static void CapitalizeWordsInSenterces ( 可从 char[l delimiterchars =. WTOX COLa ";"I"," 下载源代吗 it //. Start after Produce sentences began working System. Threading SpinWait, SpinUntil((.=>. producingsentences)i try apitalizingWords= true i This example uses this spinning for educati onal purposes // This conditi on running in a loop (spinning)is very inefficient / A. It isn't a best practice as explained in chapter 4 // Chapter 4 explained an improved version while((! sentencesBag, IsEmpty)II( producingsentence s) tring sentence iff sentencesBag. TryTake(out sentence)) capWords InsentencesBag Add t italizewords (delimiterchar ntence ")) finally 188 第5章协调数据结构 capitalizingWords false Snippet5_-13中的代码片段 如果 producing Sentences永远都不变为true,那么运行 Capitalize Sentences的 任务就会永远阻塞下去。如果将 Produce Sentences方法中给这个变量赋予true值的那一行 注释掉,就很容易理解这个状况了: private static woid Produce Sentences ( 可从 string[] possiblesentences MIUR. OIml 下载源代配 ConcurrentBag is included in the System Concurrent Collections namespace", Is parallelism important for cloud-computing? ", Parallelism is very important for cloud-computing! ", Concurrentqueue is one of the new concurrent collections added in.NET Framework 4 Concurrentstack is a concurrent collection that represents a LIFo collection lConcurrentQueue is a concurrent collection that represents a FIFo collection" } t //producingSentences =true; Snippet5_14中的代码片段 运行消费者 Capitalize WordsInSentences和 RemoveLettersIn Sentences的任务会永远等待 下去。 Spin Wait SpinUntil方法中指定的委托永远都不会返回tmue。如果使用 Break All 1命令 中止执行,并且选择 Debug| Windows| Parallel tasks打开 Parallel Tasks窗口,可以看出运 行 Produce Sentences的任务的状态为 Running,而其他两个任务的状态都是 Waiting,如图 5-13所示。这里的问题在于这些任务都会永远等待下去,而主线程也会一直等待 Parallel Invoke方法结束。因此,这个应用程序永远都不会结束执行。 ne scheduled task maghi be missing. try estarbng the debug sesac u Locaton 幽醒 AecOm A Running Snippets_&, rogr arm. ProduceSente Main An 5144 Worker Threa 1(Snippet Snippets_& Program. RemeveLefter MainAn 55 Werker This 1 Snippet 2 Wanting 68.Pregram, Capitalize or Main An 5848(Worker Threa I (Snippet_ Parallel Invoke( (->ProduceSentences(), (=> CapitalizewordsInSentenceso) (=>RemoweLettersInSentences() 图5-13 189 c#井行编程高级教程:精通NET4 Parallel Extensions 您可以使用 Spin Wait. SpinUntil方法的另一个定义,这个定义可以在第2个参数中接收 要等待的毫秒数。这个方法会返回一个bool值,表示委托是否在指定时间内返回了true。 下面的代码是一个新版本的 Capitalize WordsIn Sentences方法,其中使用了一个超时,在5秒 钟后结束等待: //5,000 milliseconds =5 seconds timeout private const int TIMEOUT = 5000: 可从 wrox.comprivatestaticvoidCapitalizewordsinsentences() char [] delimiterChars =I t } // Start after Produce sentences began working // use a 5 seconds timeout if ( System Threading Spinwait. SpinUntil( producingsentences, TIMEOUT) throw new TimeoutException( string. Format( "CapitalizeNordsInSentences has been waiting t "for【o】 seconds t。 access sentences.", TIMEOUT))i Snippet515中的代码片段 在这个示例中, Spin Wait. Spin Until方法会等待5秒钟,等待 producing Sentences变为tue 当超过这个时间之后,这个方法就会返回 false。这段代码会抛出一个 TimeoutException异 常,调用这个方法的任务会因为错误而退出。这段代码需要一个取消机制,Main方法应该 检查任务的状态并且捕捉 Aggregate Exception异常,这些在之前的示例中都已经解释过了。 553自旋和处理器出让 之前的示例使用了 Spin Wait. Spin Until方法。您可以创建 Spin Wait实例,并且利用其 方法和属性实现基本的自旋功能,并且判断新的自旋是否会让出底层线程的时间片并触发 上下文切换。 Spin Wait实例还提供了以下两个方法 Reset-一重置自旋计数器。调用这个方法能够使得 Count属性变为0, Spin Wait会 重新开始自旋计数器,就好像没有对 Spin wait实例调用过 Spinonce方法一样。 SpinOnce-执行一次自旋。然而, Spin Wait实例执行一定次数的自旋之后,如有 必要,会让出底层线程的时间片并且触发一次上下文切换。因此, Spin Wait实例 的行为会根据已经执行的次数而发生改变 Spin Wait实例公开了两个只读属性: Count-提供 Spin Wait实例通过 SpinOnce方法执行单次自旋的次数。 190

...展开详情
立即下载 最低0.43元/次 学生认证VIP会员7折
举报 举报 收藏 收藏 (2)
分享

评论 下载该资源后可以进行评论 24

tongruiliyun 非常好的资料,谢谢分享
2018-08-06
回复
zhengxiayuhexue 很不错,正在研读
2016-05-27
回复
mj_dangerous MVC使用不错,正在研究MVC,希望可以帮到我
2016-05-10
回复
landongjun 非常好的资料,谢谢分享!
2016-03-22
回复
qinghdsndskf 很好的资料,值得学习。
2015-11-05
回复
  • 1
  • 2
  • 3
  • 4
  • 5
96.54MB
C#并行编程高级教程(中文版).pdf

C#并行编程高级教程(中文版).pdf

2014-08-18 立即下载
92.83MB
C#并行编程高级教程(中文版PDF高清).rar

C#并行编程高级教程(中文版PDF高清).rar C#并行编程高级教程(中文版PDF高清).rar C#并行编程高级教程(中文版PDF高清).rar

2018-03-23 立即下载
94MB
C#并行编程高级教程

您想淋漓尽致地发挥多核计算机系统的处理能力吗?《C#并行编程高级教程:精通NET 4 Parallel Extensions》将帮助您实现这一夙愿。这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合地使用高级Intel工具与C#,并指导您巧妙使用新引入的轻型协调结构来开发自己的解决方案并解决最棘手的并发编程问题。, 主要内容, ◆介绍如何基于新Task Parallel Library和.NET 4设计稳定的

2018-01-09 立即下载
96.56MB
C#并行编程高级教程(中文版) PDF

C#并行编程高级教程 (中文版) 您想淋漓尽致地发挥多核计算机系统的处理能力吗?《c#并行编程高级教程》将帮助您实现这一夙愿。这本精品书籍浓墨重彩地描述如何使用c# 4、visual studio2010和. framework4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合地使用高级intel工具与c#,并指导您巧妙使用新引入的轻型协调结构来开发自己的解决方案并解决最棘手的并发编程问题。

2018-05-24 立即下载
93.75MB
C#并行编程高级教程(中文版)

C#多核并行编程很不错的一本书,讲解通俗易懂,讲解很深入,有利于提高编程能力

2018-11-18 立即下载
107B
C#并行编程高级教程精通:NET 4 Parallel Extensions(中文版&英文版)

花了好长时间,终于把中文版和英文版都找全了,附件为下载地址,长时间共享,若是链接无效,或是没有分下载可以留下邮箱。 文件清单: C#并行编程高级教程精通:NET 4 Parallel Extensions(英文版).pdf C#并行编程高级教程精通:NET 4 Parallel Extensions(中文版).pdf

2014-05-12 立即下载
50MB
C#并行编程高级教程 真正中文版

由于有上传限制 一共两个分卷压缩包 绝对 PROFESSIONAL PARALLEL PROGRAMMING WITH C# C#并行编程高级教程 真正中文版

2015-01-03 立即下载
96.54MB
C#并行编程高级教程 : 精通.NET 4 Parallel Extensions 中文版 PDF

原作名: Professional Parallel Programming with C# 内容简介 · · · · · · 您想淋漓尽致地发挥多核计算机系统的处理能力吗?《C#并行编程高级教程:精通NET 4 Parallel Extensions》将帮助您实现这一夙愿。这本精品书籍浓墨重彩地描述如何使用C# 4、Visual Studio 2010和.NET Framework 4高效地创建基于任务的并行应用程序,详细讲述最新的单指令、多数据流指令和向量化等并行编程技术,介绍现代并行库,讨论如何珠联璧合地使用高级Intel工具与C#,并指导您巧妙使用新引入的轻型协调结构来开发自己的解决

2016-04-11 立即下载
36.76MB
Twitter手机端安装包--Android

Android手机Twitter客户端,很多时候下载特别慢,希望对你有帮助。

2017-09-29 立即下载
1.5MB
60分钟学会OrCAD-Capture-CIS

60分钟学会OrCAD-Capture-CIS 很不错的资料,推荐给大家

2017-09-29 立即下载
1.05MB
ModbusTCP/RTU网关设计

基于UIP协议栈,实现MODBUS联网,可参考本文档资料,有MODBUS协议介绍

2017-09-30 立即下载
3.75MB
html+css+js制作的一个动态的新年贺卡

该代码是http://blog.csdn.net/qq_29656961/article/details/78155792博客里面的代码,代码里面有要用到的图片资源和音乐资源。

2017-10-03 立即下载
860KB
iCopy解码软件v1.0.1.7.exe

解ic,id,hid卡密码破解ic,id,hid卡密码破解ic,id,hid破解ic,id,hid卡破解ic,id,hid卡密码密码卡密码破解ic,id,hid卡...

2017-10-06 立即下载
img
tjoy2005
  • 签到新秀

    累计签到获取,不积跬步,无以至千里,继续坚持!

关注 私信 TA的资源

上传资源赚积分,得勋章
相关内容推荐