1.概述
對於設備文件,我們可以用阻塞和非阻塞的方式讀寫。在阻塞方式下,若設備不可讀寫,則該進程休眠,釋放CPU資源;若設備文件可讀寫,則對設備文件進行讀寫。在非阻塞方式下,若設備不可讀寫,進程放棄讀寫,繼續向下執行;若設備文件可讀寫,則對設備文件進行讀寫。
2.使用及實現原理
使用:
要使用非阻塞方式讀寫設備文件,則在調用open()函數時,添加O_NONBLOCK的mode參數,如:fd = open("filename", O_RDWR | O_NONBLOCK)。要使阻塞方式讀寫設備文件,則在調用open()函數時,不添加O_NONBLOCK的mode參數,如:fd = open("filename", O_RDWR)。
實現原理:
因爲我們在應用程序裏面調用的open、read、write函數等,經過一系列的調用過程,最終會調用到設備驅動程序裏面的xxx_open()、xxx_read()、xxx_write()函數,這些函數會判斷flags是否置位O_NONBLOCK位,若有,則當設備文件不可讀寫時,不會調用相應內核函數來阻塞進程,反之,當flags沒有置位O_NONBLOCK位,則當設備文件不可讀寫時,驅動程序調用相應內核函數來阻塞進程。
如:
static ssize_t xxx_read(struct file *file, char __user *buf, size_t size,
loff_t *ppos)
{
if(file->f_flags & O_NONBLOCK)//非阻塞
{
if(不可讀寫)
return -EAGAIN;
else //可讀寫
copy_to_user(buf, &val, sizeof(val));
}
else //阻塞
{
if(不可讀寫)
wait_event_interruptible(button_waitq, ev_press);//直接休眠
else //可讀寫
copy_to_user(buf, &val, sizeof(val));
}
}
3.總結
阻塞和非阻塞是應用程序對設備文件訪問的兩種方式,暫時不太明白具體的應用場景,阻塞方式下,設備文件不可訪問,進程就休眠,當設備文件可訪問時,喚醒進程;非阻塞方式下,設備文件不可訪問時,進程可以繼續執行。
阻塞和非阻塞機制的實現,都是靠對應的設備驅動程序。