異步編程到底在說啥?
大家好,我是小風(fēng)哥。
有的同學(xué)可能注意到了最近更新頻率有點(diǎn)慢,除了工作外小風(fēng)哥也確實(shí)在忙些其它事情,這里先賣個關(guān)子,過段時間會和大家匯報(bào)的圖片。
之前很多同學(xué)在微信上問能不能講講異步編程是怎么一回事兒,今天就和大家簡單聊一聊這個話題。
我們以函數(shù)調(diào)用為例,假設(shè)有這樣的代碼:
- void B() {
- lines = read(filename);
- sum(lines);
- }
- void A() {
- ...
- B();
- ...
- }
代碼非常簡單,B函數(shù)讀取一個文件,文件里保存的是一行行數(shù)據(jù),然后加和,A函數(shù)中的某個位置調(diào)用B函數(shù)。
此時,我們說這是同步調(diào)用,因?yàn)锳函數(shù)后續(xù)代碼必須等待B函數(shù)處理完文件才能繼續(xù)執(zhí)行。
隨著業(yè)務(wù)不斷發(fā)展,B函數(shù)處理的文件越來越龐大,此時處理一次文件耗時2小時,假設(shè)A函數(shù)后還有一行重要的代碼:
- void A() {
- ...
- B();
- something_important();
- ...
- }
這就意味著調(diào)用B函數(shù)后需要等待2個小時才能執(zhí)行到something_important這行代碼,而something_important函數(shù)對時間要求非常苛刻,該怎樣改進(jìn)呢?
其實(shí)很簡單,我們可以在B函數(shù)內(nèi)部創(chuàng)建一個線程,在線程中處理文件:
- void handle_file() {
- lines = read(filename);
- sum(lines);
- }
- void B() {
- thread t(handle_file);
- }
- void A() {
- ...
- B();
- something_important();
- ...
- }
這樣B函數(shù)被調(diào)用后創(chuàng)建完線程即可立即返回,緊接著開始執(zhí)行something_important這行代碼,CPU在執(zhí)行something_important這行代碼時可能文件還沒有開始處理,這樣函數(shù)A不再依賴于文件處理,這時我們說函數(shù)B函數(shù)就是異步調(diào)用的,函數(shù)A異步于文件處理。
如果是在單核系統(tǒng)下,CPU會不斷在處理文件線程和A函數(shù)線程間切換,看上去這兩個線程就好像在同時運(yùn)行,但如果是在多核系統(tǒng)下,這兩個線程可以真正的并行起來。
在編程語境下,異步往往和線程進(jìn)程等相關(guān)。
最后舉一個例子。
同步就好比你排隊(duì)去自助售票機(jī)取電影票(話說小風(fēng)哥已經(jīng)很久很久沒有去電影院看電影了),你必須排隊(duì)等待前一個人取完電影票才能到你,你不能在前一個取票的過程中取自己的票,這時我們說取電影票時你和前一個人是同步的。
而異步就好比去吃大餐,你在座位上看菜單點(diǎn)菜,其它人也可以點(diǎn)菜,你不需要等待其它人吃完飯才能下單,這時我們說你點(diǎn)菜和其它人吃飯是異步的。
本文轉(zhuǎn)載自微信公眾號「碼農(nóng)的荒島求生」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系碼農(nóng)的荒島求生公眾號。