非堵塞型I/O:當(dāng)數(shù)據(jù)不可用時,進(jìn)程調(diào)用read或write系統(tǒng)調(diào)用時,進(jìn)程不會堵塞,會立即返回,即使現(xiàn)在沒有數(shù)據(jù)可讀或者可寫。
非堵塞型I/O分為 兩種:顯示和隱式的。
顯示:即將filp->f_flags中的O_NONBLOCK置位。
隱式:在調(diào)用read或write系統(tǒng)調(diào)用之前,先調(diào)用poll select或者epoll 查詢該文件是否有數(shù)據(jù)可讀寫。
注釋:O_NONBLOCK只對read write 和open有效。
? ? ? ? ? ?poll select和epoll在調(diào)用過程中會堵塞。
poll 和 select(輪詢):
用來查詢某個或者多個文件描述符上的讀取或?qū)懭胧欠駮欢氯H绻F(xiàn)在沒有可以讀寫的文件描述符,則堵塞等待直到有可讀寫的文件描述符。如果有,則直接返回可以讀寫的文件描述符。
poll的實現(xiàn)(<linux/poll.h>):
方法原型:unsigned int (*poll) (struct file ? *filp, poll_table *wait);
該函數(shù)分為兩步執(zhí)行:
在一個或多個可指示poll狀態(tài)變化的等待隊列上調(diào)用poll_wait。如果當(dāng)前沒有文件描述符可用來執(zhí)行I/O,則內(nèi)核將使進(jìn)程在傳遞到該系統(tǒng)調(diào)用的所有文件描述符對應(yīng)的等待隊列上等待。
返回一個用來描述操作是否可以立即執(zhí)行的位掩碼。
poll_wait:
void poll_wait(struct file *,wait_queue_head_t *, poll_table *)
位掩碼:
POLLIN:如果設(shè)備可以無堵塞地讀取,就設(shè)置該位
POLLRDNORM:如果“通常”的數(shù)據(jù)已經(jīng)就緒,可以讀取,就設(shè)置該位。一個可讀設(shè)備返回(POLLIN | POLLRDNORM)
POLLOUT:如果設(shè)備可以無堵塞地寫入,就設(shè)置該位
POLLWRNORM:如果“通?!钡臄?shù)據(jù)已經(jīng)就緒,可以寫入,就設(shè)置該位。一個可讀設(shè)備返回(POLLOUT?| POLLWRNORM)
實例代碼(lld3 ?scull/pipe.c):
down(&dev->sem);
poll_wait(filp, &dev->inq, ?wait);
poll_wait(filp, &dev->outq,wait);
if (dev->rp != dev->wp)
? ? ? ? ? ? mask | = POLLIN | POLLRDNORM;
if (spacefree(dev))
? ? ? ? ? ? ?mask | = POLLOUT | POLLWRNORM;
up(&dev->sem);
return mask;
2016.04.14