一狈究、概念
異步:某個(gè)事情需要10s完成盏求。而我只需要調(diào)用某個(gè)函數(shù)告訴xxx來(lái)幫我做(然后我再干其他的事情)
同步:某個(gè)事情需要10s完成,我需要一直等它完成(等10s)磅废,再能繼續(xù)后面的工作荆烈。
阻塞:做某件事情,直到完成憔购,除非超時(shí)
非阻塞:嘗試做,如果不能做导绷,就不做(直接返回)屎飘,如果能做,就做钦购。
前兩者和后兩者不容易區(qū)分,不過(guò)前兩者更多的有涉及到多線程交互(消息)的場(chǎng)景葵萎。
二怨规、舉個(gè)例子
小李喝了想喝水,于是去煮開(kāi)水波丰。
1、小李把水壺放到爐子上爽蝴,等待水燒開(kāi)。(同步阻塞)
小李感覺(jué)這樣太費(fèi)時(shí)間蝎亚。
2、小李把水壺放到爐子上躺彬,去客廳看電視梅惯,時(shí)不時(shí)去廚房看看水開(kāi)沒(méi)有。(同步非阻塞)
小李還是覺(jué)得自己這樣太累铣减,于是買(mǎi)了把會(huì)響笛的那種水壺。水開(kāi)之后缔刹,能發(fā)出聲音劣针。
3、小李把響水壺放到爐子上灭翔,等待水壺發(fā)出聲音辣苏。(異步阻塞)
覺(jué)得這樣傻等意義不大
5、小李把響水壺放到爐子上稀蟋,去客廳看電視,水壺響之前不再去看它了骏融,響了再去拿壺萌狂。(異步非阻塞)
這樣真好。
三茫藏、深入理解
阻塞就是 recv/read的時(shí)候 socket接收緩沖區(qū)要是有數(shù)據(jù)就讀, 沒(méi)數(shù)據(jù)我就一直睡覺(jué)賴(lài)著不走凉当,直到有數(shù)據(jù)來(lái)了讀完我才走。send/write的時(shí)候看杭,要是發(fā)送緩沖區(qū)滿了,沒(méi)有空間繼續(xù)發(fā)送了我也一直睡覺(jué)賴(lài)著不走模孩,直到發(fā)送緩沖區(qū)騰出足夠的空間讓我把數(shù)據(jù)全部塞到發(fā)送緩沖區(qū)里我才走贮缅。(當(dāng)然如果你通過(guò)setsockopt設(shè)置了讀寫(xiě)超時(shí),超時(shí)時(shí)間到了還是會(huì)返回-1和EAGAIN,不再睡覺(jué)等待)
非阻塞就是recv/read的時(shí)候筷笨,要是接收緩沖區(qū)有數(shù)據(jù)我就讀完,沒(méi)有數(shù)據(jù)我直接帶著返回的-1和EGAIN走人轴或,絕不睡覺(jué)等待耽誤時(shí)間仰禀。write/send的時(shí)候, 要是發(fā)送緩沖區(qū)有足夠的空間答恶,就立刻把數(shù)據(jù)塞到發(fā)送緩沖區(qū)去,然后走人污呼,如果發(fā)送緩存區(qū)滿了包竹,空間不足,那直接帶著返回的-1和EAGAIN走人苗缩。
至于IO多路復(fù)用声诸,首先要理解的是,操作系統(tǒng)為你提供了一個(gè)功能彼乌,當(dāng)你的某個(gè)socket接收緩存區(qū)有數(shù)據(jù)可讀得问,或者發(fā)送緩沖區(qū)有空間可寫(xiě)的時(shí)候软免,它可以給你一個(gè)通知。這樣當(dāng)配合非阻塞的socket使用時(shí)漓骚,只有當(dāng)系統(tǒng)通知我哪個(gè)描述符可讀了榛泛,我才去執(zhí)行read操作,可以保證每次read都能讀到有效數(shù)據(jù)而不做純返回-1和EAGAIN的無(wú)用功孤个。寫(xiě)操作類(lèi)似沛简。操作系統(tǒng)的這個(gè)功能通過(guò)select/poll/epoll之類(lèi)的系統(tǒng)調(diào)用函數(shù)來(lái)使用,這些函數(shù)都可以同時(shí)監(jiān)視多個(gè)描述符的讀寫(xiě)就緒狀況椒楣,這樣,多個(gè)描述符的I/O操作都能在一個(gè)線程內(nèi)完成淆九,這就叫I/O多路復(fù)用毛俏,這里的“復(fù)用”指的是復(fù)用同一個(gè)線程。
至于事件驅(qū)動(dòng)煌寇,其實(shí)是I/O多路復(fù)用的一個(gè)另外的稱(chēng)呼唧席。