Multithreading 为什么我们需要线程和异步调用

Multithreading 为什么我们需要线程和异步调用,multithreading,asynchronous,Multithreading,Asynchronous,我的理解是,线程是一种并行处理多个事情的方式,它们共享相同的地址空间,但每个线程都有各自的堆栈。异步编程基本上是一种使用较少线程的方法。我不明白为什么仅仅有阻塞调用和每个阻塞命令的单独线程是不可取的 例如,假设我想刮去web的很大一部分。一个可能没有争议的实现可能是拥有大量异步循环。每个循环都会请求一个网页,等待以避免远程服务器过载,然后从同一网站请求另一个网页,直到完成。然后,循环将在数量少得多的线程上执行(这很好,因为它们大部分都在等待)。因此,重申一下这个问题,我不明白为什么在语言运行库中

我的理解是,线程是一种并行处理多个事情的方式,它们共享相同的地址空间,但每个线程都有各自的堆栈。异步编程基本上是一种使用较少线程的方法。我不明白为什么仅仅有阻塞调用和每个阻塞命令的单独线程是不可取的

例如,假设我想刮去web的很大一部分。一个可能没有争议的实现可能是拥有大量异步循环。每个循环都会请求一个网页,等待以避免远程服务器过载,然后从同一网站请求另一个网页,直到完成。然后,循环将在数量少得多的线程上执行(这很好,因为它们大部分都在等待)。因此,重申一下这个问题,我不明白为什么在语言运行库中维护线程池比在每个循环中只使用一个(主要是阻塞的)OS线程并让操作系统处理调度工作的复杂性更便宜?毕竟,如果将两个不同的调度器堆叠在彼此之上是如此的好,那么它仍然可以在操作系统中以这种方式实现:-)

很明显,答案是“线程很昂贵”。然而,线程只需要在上次被中断之前跟踪它到达的位置。这正是异步命令在阻塞之前需要知道的(可能通过存储回调来表示接下来会发生什么)。我想一个区别是,阻塞异步命令在定义良好的点执行,而线程可以在任何地方中断。如果在维持国家的成本方面真的存在巨大差异,那么它来自哪里?我怀疑这是堆栈的成本,因为这最多会浪费4KB的页面,所以即使是1000个阻塞线程,这也不是问题


非常感谢,如果问题很简单,我很抱歉。可能我就是想不出在Google中输入正确的咒语。

线程会消耗内存,因为即使它们什么都不做,它们也需要保留状态。如果你在一个线程上进行异步调用,它实际上(除了注册调用是在某处进行的)在需要解决之前不会消耗任何资源,因为如果它没有被积极处理,你就不关心它

如果应用程序的体系结构是以一种方式编写的,即它所需的资源与您接收的用户数/流量成线性比例(甚至更糟),那么这将是一个问题。如果您想观看某人详细谈论node.js,您可以观看这篇关于node.js的演讲


非常感谢。你答案的第一部分是有意义的。但是,您同意阻塞的异步调用需要一些资源。因此,资源消耗在数量上是线性的,就像每次调用一个线程一样。因此,第二部分可能不正确。这个链接很有帮助,但它基本上说“每个人都知道每个连接的线程都很糟糕”,而不是为什么——堆栈被提及,但不清楚为什么它很重要,因为它占用了很小的空间(或者在我看来是这样)。如果我有一个1GB的备用堆栈,我真的不需要异步编程吗?线程通常必须创建它需要访问的任何变量的新实例(这就是我所说的保留状态),这就增加了内存成本。处理器从一个线程切换到另一个线程也是不自由的,而如果在循环中处理事件,则永远不必重新启动任何内容。虽然请求确实需要缓存,但这些请求的内存空间可能是预先保留的,并且只有在大量使用的情况下才会增加。您甚至可以将这些文件写入磁盘,以满足特别长时间的请求。非常感谢您的后续工作。我想我可能理解基本原理是如何工作的。我只是不知道操作系统不能像闭包一样简洁地存储线程状态的根本原因是什么。显然,需要以页面大小的倍数分配堆栈内存,但不清楚成本是否值得避免。先发制人与合作式多任务也可能是其中的一部分,但我怀疑这会有很大的区别。也许答案只是:没有根本的原因,但是当前的OSs和语言运行时没有优化以运行多个线程?