TPL中Task执行的内联性线程重入
在没有 TPL(Task Parallel Library)之前,使用 ThreadPool 处理多线程事务及等待,可能类似如下代码:
![](/assets/blank.gif)
1 class Program 2 { 3 [ThreadStatic] 4 static int PerThreadValue; 5 6 static void Main(string[] args) 7 { 8 Console.WriteLine("Main thread: {0}", 9 Thread.CurrentThread.ManagedThreadId); 10 11 Console.WriteLine(); 12 13 for (int i = 1; i <= 5; i++) 14 { 15 AutoResetEvent signalOuter = new AutoResetEvent(false); 16 ThreadPool.QueueUserWorkItem((s) => 17 { 18 PerThreadValue = i; 19 Console.WriteLine("Launch thread: {0}, Value: {1}", 20 Thread.CurrentThread.ManagedThreadId, PerThreadValue); 21 22 AutoResetEvent signalInner = new AutoResetEvent(false); 23 ThreadPool.QueueUserWorkItem((n) => 24 { 25 Console.WriteLine(" Nested thread: {0}, Value: {1}", 26 Thread.CurrentThread.ManagedThreadId, PerThreadValue); 27 signalInner.Set(); 28 }); 29 signalInner.WaitOne(); 30 31 Console.WriteLine(" Launch back thread: {0}, Value: {1}", 32 Thread.CurrentThread.ManagedThreadId, PerThreadValue); 33 signalOuter.Set(); 34 }); 35 signalOuter.WaitOne(); 36 } 37 38 Console.ReadKey(); 39 } 40 }
![](/assets/blank.gif)
ThreadPool 会为每个应用程序域维护 FIFO 的先入先出队列,每当调用 QueueUserWorkItem 时,线程池会将给定的任务放入队列中,等到有下一个可用线程时,从队列中取出执行。
所以执行的解决过发现每个任务都执行在不同的线程上。
当 .NET Framework 4 提供 TPL 库之后,我们可以通过另一种写法来完成同样的任务。
![](/assets/blank.gif)
1 class Program 2 { 3 [ThreadStatic] 4 static int PerThreadValue; 5 6 static void Main(string[] args) 7 { 8 Console.WriteLine("Main thread: {0}", 9 Thread.CurrentThread.ManagedThreadId); 10 11 Console.WriteLine(); 12 13 for (int i = 1; i <= 5; i++) 14 { 15 Task.Factory.StartNew( 16 () => 17 { 18 PerThreadValue = i; 19 Console.WriteLine("Launch thread: {0}, Value: {1}", 20 Thread.CurrentThread.ManagedThreadId, PerThreadValue); 21 22 Task.Factory.StartNew( 23 () => 24 { 25 Console.WriteLine(" Nested thread: {0}, Value: {1}", 26 Thread.CurrentThread.ManagedThreadId, PerThreadValue); 27 }).Wait(); 28 29 Console.WriteLine(" Launch back thread: {0}, Value: {1}", 30 Thread.CurrentThread.ManagedThreadId, PerThreadValue); 31 }).Wait(); 32 } 33 34 Console.ReadKey(); 35 } 36 }
![](/assets/blank.gif)
通常,我们会看到的结果,嵌套的 Task 与外部调用及等待的 Task 使用了相同的线程池线程。
如果机器够快的话,基本上所有 Task 都在同一个线程上执行。
TPL 中使用 TaskScheduler 来调度 Task的 执行,而 TaskScheduler 有一个特性名为 “Task Inlining”。
当外部 ThreadPool 线程正在阻塞并等待嵌套的 NestedTas k完成时,NestedTask 有可能在该等待的线程上执行。
这样做的优点是可以提高性能,因为节省并重用了被阻塞的线程。
在使用可能碰到的问题:
如果使用 ThreadStatic 标记某变量,则使该变量为每线程 TLS 独立存储,同时也意图该变量始终在同一线程中共享。
但在所示例子中,如果在父 Task 及执行线程中指定了变量的值,而子 Task 及相同执行线程则使用了相同的变量值, 则在某种需求下会产生问题。
本文转自匠心十年博客园博客,原文链接:http://www.cnblogs.com/gaochundong/archive/2013/04/19/tpl_task_inlining.html,如需转载请自行联系原作者
TPL中Task执行的内联性线程重入相关推荐
- c语言中关于宏和内联说法正确的是, 2011年1月高等教育自学考试全国统一命题考试 C++程序设计试题...
版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如果有侵权请立即联系:55525090@qq.com,我 ...
- c++中内敛函数_C++ 内联函数 | 菜鸟教程
内联函数: Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数. 定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用. 优点: 当函数体比较 ...
- CSS中的块元素,内联元素,内联块元素
块元素,内联元素,内联块元素 元素就是标签,布局中常用的有三种标签,块元素.内联元素.内联块元素,了解这三种元素的特性,才能熟练的进行页面布局. 块元素 块元素,也可以称为行元素,布局中常用的标签如: ...
- mysql全联合查询,MySQL中的联合查询(内联、左联、外联、右联、全联)
联合查询效率较高,举例子来说明联合查询:内联inner join .左联left outer join .右联right outer join .全联full outer join 的好处及用法. T ...
- 玩转CSS中块元素、内联元素、内联块元素
元素就是标签,布局中常用的有三种标签,块元素.内联元素.内联块元素,了解这三种元素的特性,才能熟练的进行页面布局. 1.块元素 块元素,也可以称为行元素,布局中常用的标签如:div.p.ul.li. ...
- 在Vue中使用样式——使用内联样式
使用内联样式
- go 基准测试 找不到函数_Go 中的内联优化 | Linux 中国
本文讨论 Go 编译器是如何实现内联的,以及这种优化方法如何影响你的 Go 代码.https://linux.cn/article-12176-1.html作者:Dave Cheney译者:Xiaob ...
- 在Visual C++ 中使用内联汇编
一. 优点 使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤.在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工 ...
- 在 VC++ 中使用 内联汇编
From:https://blog.csdn.net/root19881111/article/details/8450266 VC++内联汇编(MSDN相关内容完整翻译):http://www.cp ...
最新文章
- 使用C#中的ref关键字,用2个简单例子来说明
- C++入门教程,全套C++基础教程(已更新完毕)
- 3、MySQL执行事务的语法和流程
- clustered index disadvantages in mysql
- boost::detail::sp_convertible相关的测试程序
- Windows上PHP扩展的实现,部署及应用
- 用C++解析HTTP下载下来的HTML文档
- 产生数(信息学奥赛一本通-T1361)
- 川大计算机专业导师冯子亮,问问川大计算机研究生招收的小专业有哪些
- RSA加解密用途简介及java示例
- 如何开发一款高大上的android应用的必备知识
- java jpa 教程 查询_Spring Boot JPA 使用教程
- JAVA常用框架及漏洞
- 【机器学习】TensorFlow共享GPU资源
- 报错 Duplicate keys detected
- 第十篇:SpringBoot集成支付宝接口扫码支付
- Element.closest() 兼容IE
- redhat7.6配置网络yum源
- 谭咏麟-讲不出再见-国语谐音歌词
- 6.openCV调整图像大小新思路(cv2.resize和imutils.resize)