【发布时间】:2016-04-20 08:08:41
【问题描述】:
由于两个主要原因,阻塞线程被认为是一种不好的做法:
- 线程消耗内存。
- 线程通过上下文切换花费处理时间。
以下是我对这些原因的困难:
非阻塞异步代码也应该消耗几乎相同数量的内存,因为调用堆栈应该在执行异步调用之前保存在某个地方(上下文 保存,之后全部)。如果线程效率非常低(内存方面),为什么 OS/CLR 不提供更轻量级的线程版本(只保存调用堆栈的上下文而不保存其他任何内容)?与其强迫我们以异步方式(明显更复杂、更难理解和维护)重新架构我们的程序,这不是更清洁的内存问题解决方案吗?
当线程被阻塞时,操作系统会将其置于等待状态。操作系统不会上下文切换到睡眠线程。由于超过 95% 的线程生命周期都花在睡眠上(假设这里是 IO 绑定的应用程序),因此性能损失应该可以忽略不计,因为线程的处理部分可能不会被操作系统抢占,因为它们应该跑得很快,做的工作很少。所以在性能方面,我也看不到非阻塞方法有很多好处。
我在这里遗漏了什么或者为什么这些论点有缺陷?
【问题讨论】:
-
这里并非所有线程都是平等的。阻塞 UI 线程是不好的,因为它会使应用程序无响应。
-
如果您想要拥有单线程阻塞代码,那么您当然可以。大多数现代应用程序不喜欢这样做。考虑桌面应用程序中的后台进程,您仍然希望能够与 UI 交互(例如在进程上提供进度表)。或者具有高吞吐量但后端操作繁重的 Web 应用程序,其中占用服务器线程等待操作会大大减少可能的并发用户数量。
-
它可以避免你的用户界面变得紧张。它被添加到 C# 中首先是为了让程序员有机会创建 WinRT 程序,现在称为 UWP。像打开文件这样简单的事情只能通过异步方法来完成。
-
@Dark Falcon,这就是为什么我在第一点中问为什么 OS/CLR 不为我们提供更轻量级的线程版本,而不是强迫我们将代码迁移到异步架构?如果线程由于某种原因效率低下,请解决这些低效率问题,但为什么要把这个概念抛到窗外呢?
-
我发现这个线程是相关的:stackoverflow.com/q/8546273/625332
标签: c# multithreading asynchronous scalability