同步函数与异步函数

文章出处:@126/blog/static/42438837200952751954922/

1. 同步函数与异步函数

什么是同步函数?

什么是异步函数?

它们在线程中执行时会对线程有何影响?

一个线程如何与一个异步执行的函数进行同步?

依据微软的MSDN上的解说:

(1)同步函数:当一个函数是同步执行时,那么当该函数被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回。

(2) 异步函数:如果一个异步函数被调用时,该函数会立即返回尽管该函数规定的操作任务还没有完成。

(3) 在一个线程中分别调用上述两种函数会对调用线程有何影响呢?

当一个线程调用一个同步函数时(例如:该函数用于完成写文件任务),如果该函数没有立即完成规定的操作,则该操作会导致该调用线程的挂起(将CPU的使用权交给系统,让系统分配给其他线程使用),,直到该同步函数规定的操作完成才返回,最终才能导致该调用线程被重新调度。

当一个线程调用的是一个异步函数(例如:该函数用于完成写文件任务),该函数会立即返回尽管其规定的任务还没有完成,这样线程就会执行异步函数的下一条语句,而不会被挂起。那么该异步函数所规定的工作是如何被完成的呢?当然是通过另外一个线程完成的了啊;那么新的线程是哪里来的呢?可能是在异步函数中新创建的一个线程也可能是系统中已经准备好的线程。

(4)一个调用了异步函数的线程如何与异步函数的执行结果同步呢?

为了解决该问题,调用线程需要使用“等待函数”来确定该异步函数何时完成了规定的任务。因此在线程调用异步函数之后立即调用一个“等待函数”挂起调用线程,一直等到异步函数执行完其所有的操作之后,再执行线程中的下一条指令。

我们是否已经发现了一个有趣的地方呢?!就是我们可以使用等待函数将一个异步执行的函数封装成一个同步函数。

2.同步调用与异步调用

操作系统发展到今天已经十分精巧,线程就是其中一个杰作。操作系统把 CPU 处理时间划分成许多短暂时间片,在时间 T1 执行一个线程的指令,到时间 T2 又执行下一线程的指令,各线程轮流执行,结果好象是所有线程在并肩前进。这样,编程时可以创建多个线程,在同一期间执行,各线程可以“并行”完成不同的任务。 在单线程方式下,计算机是一台严格意义上的冯·诺依曼式机器,一段代码调用另一段代码时,只能采用同步调用,必须等待这段代码执行完返回结果后,调用方才能继续往下执行。有了多线程的支持,可以采用异步调用,调用方和被调方可以属于两个不同的线程,调用方启动被调方线程后,不等对方返回结果就继续执行后续代码。被调方执行完毕后,通过某种手段通知调用方:结果已经出来,请酌情处理。 计算机中有些处理比较耗时。调用这种处理代码时,调用方如果站在那里苦苦等待,会严重影响程序性能。例如,某个程序启动后如果需要打开文件读出其中的数据,再根据这些数据进行一系列初始化处理,程序主窗口将迟迟不能显示,让用户感到这个程序怎么等半天也不出来,太差劲了。借助异步调用可以把问题轻松化解:把整个初始化处理放进一个单独线程,主线程启动此线程后接着往下走,让主窗口瞬间显示出来。等用户盯着窗口犯呆时,初始化处理就在背后悄悄完成了。程序开始稳定运行以后,还可以继续使用这种技巧改善人机交互的瞬时反应。用户点击鼠标时,所激发的操作如果较费时,再点击鼠标将不会立即反应,整个程序显得很沉重。借助异步调用处理费时的操作,让主线程随时恭候下一条消息,用户点击鼠标时感到轻松快捷,肯定会对软件产生好感。 异步调用用来处理从外部输入的数据特别有效。假如计算机需要从一台低速设备索取数据,然后是一段冗长的数据处理过程,采用同步调用显然很不合算:计算机先向外部设备发出请求,然后等待数据输入;而外部设备向计算机发送数据后,也要等待计算机完成数据处理后再发出下一条数据请求。双方都有一段等待期,拉长了整个处理过程。其实,计算机可以在处理数据之前先发出下一条数据请求,然后立即去处理数据。如果数据处理比数据采集快,要等待的只有计算机,外部设备可以连续不停地采集数据。如果计算机同时连接多台输入设备,可以轮流向各台设备发出数据请求,并随时处理每台设备发来的数据,整个系统可以保持连续高速运转。编程的关键是把数据索取代码和数据处理代码分别归属两个不同的线程。数据处理代码调用一个数据请求异步函数,然后径自处理手头的数据。待下一组数据到来后,数据处理线程将收到通知,结束 wait 状态,发出下一条数据请求,然后继续处理数据。 异步调用时,调用方不等被调方返回结果就转身离去,因此必须有一种机制让被调方有了结果时能通知调用方。在同一进程中有很多手段可以利用,笔者常用的手段是回调、event 对象和消息。 回调:回调方式很简单:调用异步函数时在参数中放入一个函数地址,异步函数保存此地址,待有了结果后回调此函数便可以向调用方发出通知。如果把异步函数包装进一个对象中,可以用事件取代回调函数地址,通过事件处理例程向调用方发通知。  event: event 是 Windows 系统提供的一个常用同步对象,以在异步处理中对齐不同线程之间的步点。如果调用方暂时无事可做,可以调用 wait 函数等在那里,此时 event 处于 nonsignaled 状态。当被调方出来结果之后,把 event 对象置于 signaled 状态,wait 函数便自动结束等待,使调用方重新动作起来,从被调方取出处理结果。这种方式比回调方式要复杂一些,速度也相对较慢,但有很大的灵活性,可以搞出很多花样以适应比较复杂的处理系统。

没有伞的孩子必须努力奔跑!

同步函数与异步函数

相关文章:

你感兴趣的文章:

标签云: