线程与异步


81

我一直在阅读这篇非常好的文章,以了解编程的线程模型与异步模型。http://krondo.com/blog/?p=1209

但是,本文提到以下几点。

  1. 只要有I / O,异步程序就会在任务之间切换,从而胜过同步程序。
  2. 线程由操作系统管理。

我记得曾经读过线程是由操作系统通过在Ready-Queue和Waiting-Queue(以及其他队列)之间移动TCB来管理的。在这种情况下,线程也不会浪费时间等待它们?

鉴于上述情况,异步程序比线程程序有什么优势?


5
不,我的意思是线程与异步。我之所以提到第一点,只是因为我从这篇文章中了解了这一点。

Answers:


78
  1. 编写线程安全的代码非常困难。使用异步代码,您可以确切地知道代码将从一个任务转移到下一个任务的位置,因此很难获得竞争条件。
  2. 线程消耗大量数据,因为每个线程需要拥有自己的堆栈。使用异步代码,所有代码共享同一堆栈,并且由于在任务之间不断展开堆栈,因此堆栈保持较小。
  3. 线程是OS结构,因此是平台要支持的更多内存。异步任务没有这样的问题。

12
详细说明:1.线程代码的I / O部分相对容易,但是在没有竞争条件的情况下管理线程之间的共享状态(使用锁/队列/等)非常棘手。使用异步模型意味着您减少了同时进行的时间,因此很容易避免种族。2/3。每个线程将至少消耗一个堆栈的内存页(通常为4KB或8KB),以及与该线程状态相关的其他数据结构的一些未知的内存量。
Dobes Vandermeer


7
  1. 假设您有2个任务,不涉及任何IO(在多处理器计算机上)。在这种情况下,线程的性能优于异步。因为异步就像单线程程序一样按顺序执行任务。但是线程可以同时执行两个任务。

  2. 假设您有2个任务,涉及IO(在多处理器计算机上)。在这种情况下,Async和Threads或多或少地执行相同的操作(性能可能会因核心数,调度,任务的进程密集程度等而异)。同样,异步也占用较少的资源,较低的开销,并且通过多线程程序进行编程的复杂性较低。

这个怎么运作?线程1执行任务1,因为它正在等待IO,所以将其移至IO等待队列。同样,线程2执行任务2,因为它也涉及IO,因此将其移至IO等待队列。IO请求一经解决,便将其移至就绪队列,以便调度程序可以调度线程以供执行。

异步执行任务1,并且不等待它的IO完成而继续执行任务2,然后等待两个任务的IO完成。它按IO完成的顺序完成任务。

异步最适合涉及Web服务调用,数据库查询调用等任务的线程,用于处理流程密集型任务的线程。

以下视频介绍了有关使用时间Async vs Threaded model以及使用时间等信息, https://www.youtube.com/watch?v = kdzL3r-yJZY

希望这会有所帮助。


2
始终欢迎潜在解决方案的链接,但是请在该链接周围添加上下文,以便您的其他用户会知道它的含义和存在的原因。如果目标站点无法访问或永久离线,请始终引用重要链接中最相关的部分。考虑到为什么仅删除一个外部站点的链接以及为什么删除一些答案是可能的原因
Machavity

4

首先,请注意,有关如何实现和调度线程的许多细节都是特定于操作系统的。通常,您不必担心线程彼此等待,因为OS和硬件会尝试安排它们高效运行,而不管它们是在单处理器系统上异步运行还是在多处理器上并行运行。

一旦线程完成了等待某事(例如I / O),就可以认为它是可运行的。可运行的线程将计划在不久的某个时间执行。同样,将其实现为简单队列还是更复杂的特定于OS和硬件。您可以将阻塞线程集视为一组,而不是严格排序的队列。

请注意,在单处理器系统上,此处定义的异步程序等效于线程程序。


0

异步I / O意味着驱动程序中已经有一个线程可以完成这项工作,因此您正在复制功能并产生一些开销。另一方面,通常没有记录驱动程序线程的行为方式,在复杂的情况下,当您想要控制超时/取消/启动/停止行为,与其他线程同步时,实现自己的线程是有意义的。有时也更容易以同步方式进行推理。


5
这根本不是异步I / O的工作方式。从根本上讲,I / O是事件驱动的(您启动设备的I / O,稍后,设备完成它,并希望通过中断告诉您)。在某些I / O(如磁盘I / O)中,驱动程序出于某种晦涩的原因而使用内核线程。但是对于网络而言,它一直是异步操作。
Glyph

0

参见http://en.wikipedia.org/wiki/Thread_(computing)#I.2FO_and_scheduling

但是,在用户线程(与内核线程相反)或光纤中使用阻塞系统调用可能会出现问题。如果用户线程或光纤执行了阻塞的系统调用,则该进程中的其他用户线程和光纤将无法运行,直到系统调用返回。此问题的典型示例是在执行I / O时:大多数程序被编写为同步执行I / O。启动I / O操作时,将进行系统调用,并且直到I / O操作完成后才返回。在此期间,整个进程被内核“阻塞”并且无法运行,这使同一进程中的其他用户线程和光纤无法执行。

据此,您的整个过程可能被阻塞,并且在IO中阻塞一个线程时,将不会调度任何线程。我认为这是特定于OS的,并且不会一直保持下去。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.