Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 設備驅動實戰:阻塞與非阻塞 I/O 完整範例解析

編輯:Linux 教學

阻塞操作指進程在無法獲得資源時掛起(睡眠),直到條件滿足才繼續;非阻塞則直接返回。Linux 驅動中通過等待隊列實現阻塞,等待隊列作為內核異步事件通知的基礎機制,與進程調度緊密結合,信號量內部也基於等待隊列實現。

完整驅動程式範例:globalvar 字符設備

該設備允許多進程打開,但規定:只有當有進程寫入數據後,本進程或其他進程才能讀取該數據,否則讀操作一直阻塞。使用信號量保護共享變量,等待隊列實現讀寫同步。

核心數據結構

static int global_var = 0;          // 共享數據
static struct semaphore sem;        // 互斥信號量
static wait_queue_head_t outq;      // 等待隊列頭
static int flag = 0;                // 數據就緒標誌

初始化與清理

static int __init globalvar_init(void) {
    int ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
    if (!ret) {
        init_MUTEX(&sem);
        init_waitqueue_head(&outq);
    }
    return ret;
}
static void __exit globalvar_exit(void) {
    unregister_chrdev(MAJOR_NUM, "globalvar");
}

讀操作:阻塞等待數據

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off) {
    // 1. 等待數據就緒(可被信號中斷)
    if (wait_event_interruptible(outq, flag != 0))
        return -ERESTARTSYS;

    // 2. 獲取信號量保護臨界區
    if (down_interruptible(&sem))
        return -ERESTARTSYS;

    flag = 0; // 清除標誌
    if (copy_to_user(buf, &global_var, sizeof(int))) {
        up(&sem);
        return -EFAULT;
    }
    up(&sem);
    return sizeof(int);
}

寫操作:寫入數據並喚醒等待者

static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off) {
    if (down_interruptible(&sem))
        return -ERESTARTSYS;

    if (copy_from_user(&global_var, buf, sizeof(int))) {
        up(&sem);
        return -EFAULT;
    }
    up(&sem);

    flag = 1; // 設置數據就緒
    wake_up_interruptible(&outq); // 喚醒所有等待讀的進程
    return sizeof(int);
}

用戶態測試程式

編寫兩個程式:一個阻塞讀 /dev/globalvar,另一個寫入數據。打開兩個終端分別運行,寫端輸入數值後,讀端立即輸出該值,驗證阻塞/喚醒機制正常工作。

關鍵點補充:鎖與等待隊列的順序

若將 down_interruptible() 放在 wait_event_interruptible() 之前,會導致持有鎖睡眠,嚴重降低並發性能甚至死鎖。正確順序是先等待條件滿足,再獲取鎖訪問臨界資源,如範例所示。

Copyright © Windows教程網 All Rights Reserved