异步调用是否总是创建一个新线程?两者有什么区别?
异步调用是否总是创建或使用新线程?
在计算机编程中,异步事件是独立于主程序流程而发生的事件。异步动作是在非阻塞方案中执行的动作,允许主程序流继续进行处理。
我知道异步调用可以在单线程上完成吗?这怎么可能?
异步调用是否总是创建一个新线程?两者有什么区别?
异步调用是否总是创建或使用新线程?
在计算机编程中,异步事件是独立于主程序流程而发生的事件。异步动作是在非阻塞方案中执行的动作,允许主程序流继续进行处理。
我知道异步调用可以在单线程上完成吗?这怎么可能?
Answers:
这个问题太笼统了,无法回答。
在一般情况下,异步调用不一定会创建新线程。这是实现它的一种方法,而预先存在的线程池或外部进程是其他方法。它在很大程度上取决于语言,对象模型(如果有)和运行时环境。
异步只是意味着调用线程不坐下来等待响应,异步活动也不会在调用线程中发生。
除此之外,您将需要更加具体。
每当需要异步进行的操作不需要CPU进行工作时,就可以在不产生另一个线程的情况下完成该操作。例如,如果异步操作是I / O,则CPU不必等待I / O完成。它只需要开始操作,然后可以在I / O硬件(磁盘控制器,网络接口等)执行I / O工作时继续进行其他工作。硬件通过中断CPU来通知CPU完成时间,然后OS将事件传递给您的应用程序。
通常,更高级别的抽象和API不会公开来自操作系统和基础硬件的基础异步API。在这种情况下,即使生成的线程只是在等待I / O操作,通常也更容易创建线程来执行异步操作。
如果异步操作需要CPU完成工作,那么通常该操作必须在另一个线程中进行才能真正实现异步。即使那样,如果存在多个执行单元,它实际上也将是异步的。
不,异步调用并不总是涉及线程。
它们通常确实会启动某种操作,该操作与调用方并行进行。但是该操作可能由另一个进程,操作系统,其他硬件(如磁盘控制器),网络上的其他计算机或人来处理。线程并不是并行完成任务的唯一方法。
JavaScript是单线程和异步的。例如,当您使用XmlHttpRequest时,将为它提供一个回调函数,该函数将在响应返回时异步执行。
John Resig很好地解释了计时器如何在JavaScript中工作的相关问题。
多线程是指在同一进程中发生的多个操作。而异步编程则跨进程进行。例如,如果我的操作调用了Web服务,则线程不必等到Web服务返回。在这里,我们使用异步编程,该编程允许线程不等待另一台计算机上的进程完成。当它开始从Web服务获取响应时,它可以中断主线程,以表明Web服务已完成对请求的处理。现在,主线程可以处理结果。
由于非抢占时间(版本2.13、3.0、3.1等)使用消息循环(在支持实线程之前),Windows始终具有异步处理。因此,要回答您的问题,不,没有必要创建线程来执行异步处理。
异步呼叫甚至不需要与调用该呼叫的系统/设备在同一系统/设备上进行。因此,如果问题是,异步调用在当前进程中是否需要线程,答案是否定的。但是,在处理异步请求的某处必须有一个执行线程。
执行线程是一个模糊的术语。在早期的Macintosh和Windows OS之类的协作式任务系统中,执行线程可能只是使请求运行另一个堆栈,指令指针等的同一进程。但是,当人们通常谈论异步调用时,它们通常表示由另一个线程(如果在进程内(即,在同一进程内))处理,或者由另一个进程(在进程间)进行处理。
请注意,进程间(或进程间)通信(IPC)通常被概括为包括进程内通信,因为锁定和同步数据的技术通常是相同的,而与执行各个执行线程所处的进程无关。
有些系统允许您使用回调的某些功能来利用内核中的并发性。对于一个相当模糊的实例,在Mac System 6-8的无抢占式多任务处理时代,异步IO回调用于实现无阻塞Internet服务器。
这样,您就可以在程序中“并发”执行并发执行流,而无需这样的线程。
异步调用的性质是,如果您希望应用程序在调用过程中继续运行,则需要生成一个新线程,或者至少要利用您自己创建的另一个线程来专门用于以下目的:处理异步回调。
有时,根据情况,您可能想调用一个异步方法,但使它在用户看来是同步的(即阻塞,直到异步方法已完成该信号为止)。这可以通过Win32 API(例如WaitForSingleObject)来实现。