本文主要介紹在網(wǎng)絡(luò)請(qǐng)求中的同步與異步,以及異步的表現(xiàn)形式: 回調(diào)與協(xié)程,并通過python代碼展示各自的優(yōu)缺點(diǎn)。
概念上下文:
當(dāng)提到同步與異步,大家不免會(huì)想到另一組詞語(yǔ):阻塞與非阻塞。通常,同時(shí)提到這個(gè)這幾個(gè)詞語(yǔ)一般實(shí)在討論network io的時(shí)候,在《unix network programming》中有詳盡的解釋,網(wǎng)絡(luò)中也有許多講解生動(dòng)的文章。
本文所討論的同步與異步,是指對(duì)于請(qǐng)求的發(fā)起者,是否需要等到請(qǐng)求的結(jié)果(同步),還是說請(qǐng)求完畢的時(shí)候以某種方式通知請(qǐng)求發(fā)起者(異步)。在這個(gè)語(yǔ)義環(huán)境下,阻塞與非阻塞,是指請(qǐng)求的受理者在處理某個(gè)請(qǐng)求的狀態(tài),如果在處理這個(gè)請(qǐng)求的時(shí)候不能做其它事情(請(qǐng)求處理時(shí)間不確定),那么稱之為阻塞,否則為非阻塞。
舉個(gè)例子,我去柜臺(tái)辦理業(yè)務(wù),那我是請(qǐng)求者,柜員時(shí)受理者。如果我在柜臺(tái)一直等著柜員辦理,直到辦理完畢,那么對(duì)于我來說,就是同步的;如果我只是在柜員那里登記,然后到一邊歇著,等柜員辦理完畢之后告訴我結(jié)果,那么就是異步的。對(duì)于柜員,辦理業(yè)務(wù)的時(shí)候可能需要等待打印機(jī)打印,如果在這個(gè)時(shí)候柜員去處理其他人的業(yè)務(wù),那么就是非阻塞的,如果一定得到把我的業(yè)務(wù)辦完再接待下一位顧客,那么就是阻塞的。
本文站在請(qǐng)求發(fā)起者的角度來思考同步與異步,在實(shí)際開發(fā)中,一個(gè)最簡(jiǎn)單的例子就是http請(qǐng)求。假設(shè)這么一個(gè)場(chǎng)景,程序需要訪問兩個(gè)網(wǎng)址(通過url),如果只有一個(gè)線程。那么同步與異步分別怎么處理呢
同步的方式:
python的urllib2提供了http請(qǐng)求的功能,我們來看看代碼:
1 def http_blockway(url1, url2): 2 import urllib2 as urllib 3 import time 4 begin = time.time() 5 data1 = urllib.urlopen(url1).read() 6 data2 = urllib.urlopen(url2).read() 7 print len(data1), len(data2) 8 print 'http_blockway cost', time.time() - begin 9 10 url_list = [ 'http://xlambda.com/gevent-tutorial/','https://www.bing.com']11 if __name__ == '__main__':1