我一直在阅读关于线程模型和异步模型的编程,来自这篇非常好的文章。 http://krondo.com/blog/?p=1209
然而,这篇文章提到了以下几点。
- 每当有I/O操作时,异步程序将通过在任务之间切换来简单地优化同步程序。
- 线程由操作系统管理。
我记得读过线程由操作系统管理,通过在Ready-Queue和Waiting-Queue之间移动线程控制块(TCB)(以及其他队列)来实现。在这种情况下,线程也不会浪费等待时间,是吗?
基于上述内容,请问异步程序相对于线程程序有哪些优势?
我一直在阅读关于线程模型和异步模型的编程,来自这篇非常好的文章。 http://krondo.com/blog/?p=1209
然而,这篇文章提到了以下几点。
我记得读过线程由操作系统管理,通过在Ready-Queue和Waiting-Queue之间移动线程控制块(TCB)(以及其他队列)来实现。在这种情况下,线程也不会浪费等待时间,是吗?
基于上述内容,请问异步程序相对于线程程序有哪些优势?
许多语言现在支持无堆栈协程(async/await)。这使我们能够几乎同步地编写任务,同时在设置的位置(睡眠或等待网络或其他线程)中让出其他任务(await
)。
res = await task
更容易获取、共享和理解延迟任务的结果,而在单独的线程中执行代码需要使用共享对象(如队列)来获取结果。 - MjH创建线程有两种方式:
同步线程 - 父进程创建一个或多个子线程,然后必须等待每个子线程终止。同步线程通常被称为分叉-合并模型。
异步线程 - 父进程和子进程同时/独立地运行。多线程服务器通常遵循这种模型。
来源 - http://www.amazon.com/Operating-System-Concepts-Abraham-Silberschatz/dp/0470128720
假设您有2个任务,不涉及任何IO(在多处理器机器上)。 在这种情况下,线程优于Async。因为Async像单线程程序一样按顺序执行您的任务。但是线程可以同时执行两个任务。
假设您有2个涉及IO的任务(在多处理器机器上)。 在这种情况下,Async和Threads表现出更或多或少相同的性能(性能可能会因核心数、调度、任务的进程密集程度等而有所不同)。此外,与多线程程序相比,Async需要更少的资源、低开销和较少的编程复杂性。
它如何工作? 线程1执行任务1,因为它正在等待IO,所以被移到IO等待队列中。类似地,线程2执行任务2,因为它也涉及IO,所以被移到IO等待队列中。一旦其IO请求得到解决,它就被移到准备队列中,以便调度程序可以安排线程进行执行。
Async执行任务1,而不等待其IO完成,然后继续执行任务2,然后等待两个任务的IO完成。它按IO完成的顺序完成任务。
Async最适合涉及Web服务调用、数据库查询调用等任务, 线程适用于进程密集型任务。
下面的视频介绍了Async vs Threaded model
以及何时使用等,
https://www.youtube.com/watch?v=kdzL3r-yJZY
希望这有所帮助。
请参见 http://en.wikipedia.org/wiki/Thread_(computing)#I.2FO_and_scheduling。
然而,在用户线程(相对于内核线程)或纤程中使用阻塞系统调用可能会有问题。如果用户线程或纤程执行了一个阻塞的系统调用,进程中的其他用户线程和纤程将无法运行,直到系统调用返回。这个问题的典型例子是当执行 I/O 时: 大多数程序都是同步执行 I/O 的。当启动 I/O 操作时,会进行系统调用,并且在 I/O 操作完成之前不会返回。在此期间,整个进程被内核"阻塞",不能运行,从而使得同一进程中的其他用户线程和纤程无法执行。
根据此情况,当一个线程在 IO 中被阻塞时,整个进程可能会被阻塞,没有线程会被调度。我认为这取决于操作系统,并不总是成立。
异步 I/O 意味着驱动程序中已经有一个线程在执行任务,因此您正在复制功能并产生一些开销。另一方面,通常没有文档说明驱动程序线程的确切行为,在复杂的情况下,当您想要控制超时/取消/启动/停止行为、与其他线程同步时,实现自己的线程是有意义的。有时候以同步方式进行推理也更容易。