首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux poll() 系統調用完整指南:驅動層實現與用戶態測試代碼

     編輯:關於C語言

poll() 核心機制

監視多個文件描述符事件,無事件時進程睡眠釋放 CPU,有事件喚醒並返回就緒集合。struct pollfd 每次調用前需重新設置。

驅動層實現關鍵點(字符設備按鍵中斷為例)

/* 等待隊列頭 */
static DECLARE_WAIT_QUEUE_HEAD(wq);
static int key_event = 0;  // 條件標誌

/* 中斷處理:置位喚醒 */
irqreturn_t key_isr(int irq, void *dev) {
    key_value = gpio_get_value(KEY_GPIO);
    key_event = 1;
    wake_up_interruptible(&wq);
    return IRQ_HANDLED;
}

/* poll 入口:掛接等待隊列,檢查條件 */
unsigned int key_poll(struct file *filp, poll_table *wait) {
    poll_wait(filp, &wq, wait);  // 將當前進程加入 wq
    if (key_event)
        return POLLIN | POLLRDNORM;  // 有數據可讀
    return 0;
}

/* read 入口:清理條件,複製數據 */
ssize_t key_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) {
    wait_event_interruptible(wq, key_event);  // 也可不調用,由用戶態 poll 保證
    key_value = gpio_get_value(KEY_GPIO);
    copy_to_user(buf, &key_value, sizeof(key_value));
    key_event = 0;
    return sizeof(key_value);
}

用戶態測試程序

int main() {
    int fd = open("/dev/key", O_RDWR);
    struct pollfd pfd = { .fd = fd, .events = POLLIN };
    
    while (1) {
        memset(&pfd, 0, sizeof(pfd));  // poll 後結構被清零,必須重置
        pfd.fd = fd; pfd.events = POLLIN;
        
        int ret = poll(&pfd, 1, 5000);  // 5秒超時
        if (ret < 0) { perror("poll"); break; }
        if (ret == 0) { puts("Timeout"); continue; }
        if (pfd.revents & POLLERR) { puts("Device error"); break; }
        if (pfd.revents & POLLIN) {
            int val; read(fd, &val, sizeof(val));
            printf("Key: %d\n", val);
        }
    }
    close(fd);
    return 0;
}

關鍵注意事項

  1. pollfd 每次循環必須 memset 重置,內核返回時會清零
  2. events 是輸入(關心什麼),revents 是輸出(實際發生什麼)
  3. 驅動中 poll_wait 不會睡眠,只是掛接;真正睡眠在用戶態 poll()
  4. 中斷處理極簡單,耗時操作放用戶態或工作隊列

Android 編譯集成 (Android.mk)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := polltest
LOCAL_SRC_FILES := polltest.c
LOCAL_SHARED_LIBRARIES := liblog libcutils
include $(BUILD_EXECUTABLE)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved