一、簡述
? 最近對javasrcip的運行機制有在研究螺垢,這里是對一些知識點對一下拓展和展開倡勇,之前有記錄過關于線程和進程的相關點馍盟,在學習過程中,有試過查閱網上的資料,網上資料感覺比較零散说墨,有和同學互相討論過,這次來記錄一下對IO事件里面的「同步」「異步」「阻塞」和「非阻塞」的一些學習迹淌。
后面越理解越覺得是接觸到一個比較大的領域顷牌,對于客戶端的JavaScript和nodeJS加深了自己的理解,在這里做一下自己的一些理解返劲。
二玲昧、定義
? 其實在思考這個問題的時候,有一個疑問就是:
同步篮绿、異步與阻塞孵延、非阻塞,這四種概念會不會是屬于IO層(當然是IO接口)的一個范疇之類的亲配?
? 于是我?guī)е@個疑問進行了一次驗證和學習尘应,希望能有一個比較清晰的理解。
先在這里理清楚4個概念:
PART 1:同步吼虎、異步【代碼指令的執(zhí)行順序】
同步:當程序代碼在執(zhí)行IO操作的時候犬钢,必須要等待上一個IO操作完成之后才能進行下一步操作的過程。
? 舉個例子:現在有A代碼指令和B代碼指令思灰,A代碼指令先于B代碼指令被操作娜饵,如果B指令代碼想要執(zhí)行的條件是A指令代碼先執(zhí)行完,那就叫做同步官辈。
?? 這里說一下就是箱舞,很多時候,我們覺得代碼一行行下來執(zhí)行就是同步拳亿,其實這樣的想法是錯的晴股,就我目前接觸的代碼很多時候是一行一行執(zhí)行,但是這是沒有一些IO操作的情況下肺魁,當遇到文件讀寫电湘、數據庫之類等等之類的情況時,這就不是一行一行代碼執(zhí)行了,不同的語言有不同的內部運行機制寂呛,javascript的運行機制就是一個例子怎诫。
下面是使用javasrcipt編寫的demo.
異步:當程序代碼在執(zhí)行IO操作的時候,不必等待上一個IO操作完后才執(zhí)行的過程贷痪。
? 舉個例子:現在有A代碼指令和B代碼指令幻妓,A代碼指令位置先于B代碼指令被操作,如果B指令代碼執(zhí)行的條件是不需要去等待A指令代碼先執(zhí)行完劫拢,而是可以在A代碼指令在等待或者執(zhí)行的過程中肉津,B指令代碼已經在執(zhí)行或者執(zhí)行完,那就叫做異步舱沧。
PART 1總結:
由此可見妹沙,同步和異步是在用戶層面進行操作,是在代碼指令的執(zhí)行順序進行談及熟吏。
PART 2:阻塞距糖、非阻塞【進程和線程的執(zhí)行與調用過程】
阻塞 :當應用進程開始執(zhí)行時或者被系統調用的時候,如果當前應用進程途中遇到被操作系統掛起等待另外一個應用進程執(zhí)行完才能繼續(xù)執(zhí)行的情況牵寺,或者如果當前應用進程內部的線程被調用時遇到被操作系統掛起等待另外一個線程執(zhí)行完才能繼續(xù)執(zhí)行的情況悍引,就叫阻塞。
? 舉個例子:使用javascript去編寫不含異步操作的代碼缸剪,那編寫得出來的代碼就是一個阻塞的操作,因為javascript本身就是單線程語言东亦。例如上圖給出的圖片杏节。
?記住單線程同步處理IO就是阻塞操作;
?記住單線程同步處理IO就是阻塞操作典阵;
?記住單線程同步處理IO就是阻塞操作奋渔;
?但是同步異步 與 阻塞非阻塞 二者之間并沒有必然的關系
非阻塞 :當應用進程開始執(zhí)行時或者被系統調用的時候,如果當前應用進程途中不需要等待其他應用進程完成才執(zhí)行的情況壮啊,或者當前應用進程中的進程不需要等待其他線程完成才去執(zhí)行的情況嫉鲸,這個過程叫作非阻塞。
? 舉個例子:nodeJs是一個異步非阻塞的IO模型歹啼,文件讀寫是一個異步操作玄渗,然后同時也是一個非阻塞的操作。如下圖所示狸眼。
?這個程序是先執(zhí)行step 1藤树,但是stpe 2 在step1執(zhí)行的過程中也是在執(zhí)行,是不需要等待step 1先執(zhí)行完在執(zhí)行的拓萌,是一個非阻塞的操作岁钓。
???PART 3:同步異步 與 阻塞非阻塞 二者之間并沒有必然的關系
同步異步 與 阻塞非阻塞 二者之間并沒有必然的關系,他們是可以互相組合的。
Linux經典的IO模型有詳細講解屡限,可以參考《unix環(huán)境高級編程》《unix網絡編程》這兩本書品嚣。
分別有詳細講解關于,CPU層級的IO模型和網絡編程上的IO模型钧大。
如果有不對的地方翰撑,請一定要指出哈~
關于同步、異步拓型、阻塞和非阻塞额嘿,所涉及的東西比較多,可能我了解的不夠深劣挫,可能在這里說不完整册养,希望以后有深的理解,繼續(xù)更新這篇文章压固。