天天看點

io-同步 異步 阻塞 非阻塞

異步io是kernel幫你的線程盯着該線程所要的資料是否可用,而線程可以去做别的事情。當資料可用時kernel會把資料拷貝到指定的記憶體位址然後通知通知你的線程。需要利用事件等機制來完成。

同步io是你的線程自己去向核心查詢所要的資料是否可用。在查詢的時候,資料不可用的話:

如果核心将這個線程塞進等待隊列,直到資料可用時,核心将線程加進可運作隊列,并将可用資料給它,則是阻塞型io;

如果核心不将其塞進等待隊列,而是直接給他一個error代碼表示資料不可用,則是非阻塞io。執行非阻塞型io的線程需要一遍一遍的去詢問核心資料是否可用,否則它可能讀不到可用的資料。

可見-同步 異步 阻塞 非阻塞的關系。

①異步同步是指線程對資料擷取的方式而言的,

異步:核心主動通知線程讀寫已經完成,

同步:線程主動詢問核心讀寫就緒,可以去讀或寫了。

②而阻塞非阻塞是線上程主動詢問核心時,核心對線程的不同處理方式。是以阻塞非阻塞都是在同步的情況下發生的。

|----異步

|----同步|-----阻塞

             |-----非阻塞

執行同步io時,就是直接向核心索取資料,非阻塞io(r如read函數)會立即傳回,阻塞io(如read函數)則在資料可用時傳回。線程中需要對傳回值檢查,傳回值一般是資料不可用時的錯誤代碼或可用資料。

執行異步io時,就像向核心送出一個"申請當資料可用時的事件通知"的服務(是以可以立即傳回),是以需要向核心送出一個事件參數,當資料可用時,核心自動讀寫資料到指定的記憶體位址并觸發該事件。

當然執行異步io的談不上阻塞非阻塞,因為他在執行異步io(比如read)時核心沒機會沒理由将它阻塞。

http://blog.csdn.net/historyasamirror/article/details/5778378

https://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/

2014-11-24 18:25:15

1.select ,poll,epoll都是同步非阻塞的函數

對于select而言:

應用程式在open的時候需要設定O_NONBLOCK标志,這樣在read的時候如果無資料可讀,則會直接傳回。

是以這種情況下,需要先調用select函數,對應驅動中的poll函數,如果驅動中無資料可讀,驅動會将此線程加入等待隊列,有資料可讀時(和其他一些情況)就會喚醒對應線程。線程繼續執行就直接調用read函數去讀取資料就可以讀到資料。

linux下socket沒有實作異步

linux下序列槽沒有實作異步

但是都實作了同步非阻塞,如下是serial_core.c中的poll接口

static const struct tty_operations uart_ops = {
	.open		= uart_open,
	.close		= uart_close,
	.write		= uart_write,
	.put_char	= uart_put_char,
	.flush_chars	= uart_flush_chars,
	.write_room	= uart_write_room,
	.chars_in_buffer= uart_chars_in_buffer,
	.flush_buffer	= uart_flush_buffer,
	.ioctl		= uart_ioctl,
	.throttle	= uart_throttle,
	.unthrottle	= uart_unthrottle,
	.send_xchar	= uart_send_xchar,
	.set_termios	= uart_set_termios,
	.set_ldisc	= uart_set_ldisc,
	.stop		= uart_stop,
	.start		= uart_start,
	.hangup		= uart_hangup,
	.break_ctl	= uart_break_ctl,
	.wait_until_sent= uart_wait_until_sent,
#ifdef CONFIG_PROC_FS
	.proc_fops	= &uart_proc_fops,
#endif
	.tiocmget	= uart_tiocmget,
	.tiocmset	= uart_tiocmset,
	.get_icount	= uart_get_icount,
#ifdef CONFIG_CONSOLE_POLL
	.poll_init	= uart_poll_init,
	.poll_get_char	= uart_poll_get_char,
	.poll_put_char	= uart_poll_put_char,
#endif
};
           

2017-6-16

對于io複用的使用有一個套路,叫reactor模式。使用這種架構寫代碼和直接使用io複用函數相比,主要是把業務作為回調函數去注冊,這樣事件發生時調用回調函數,進而實作業務代碼和基礎設施代碼分離。

io-同步 異步 阻塞 非阻塞

當然,reactor架構一般會把作業系統的大多數io事件都會內建進來.比如libev就實作了檔案變化事件,網絡io事件,定時器事件等

根據reator架構用多少個線程去執行回調函數,還可以初步分為單線程reactor和多線程reactor

和reactor相對的是proactor架構,他是把作業系統的異步函數用回調的機制實作出來。

同步阻塞的核心實作:

同步非阻塞的額核心實作:

2.異步io模型

先看一個例子

異步的核心實作:

繼續閱讀