linux字符设备驱动程序的设计之休眠
休眠对进程来说,意味着等待将来的某个时间发生。如何以安全的方式进入休眠,需要注意以下两点:
永远不要在原子上下文中进入休眠。
当进程被唤醒时,我们永远无法知道休眠了多长时间,或者休眠期间发生了什么事情。
等待队列就是一个进程链表,其中包含了等待某个特定事件的所有进程。在linux中,一个等待队列通过一个“等待队列头(wait quene head)”来管理,等待队列头是一个类型为wait_quene_head_t的结构体,定义在<linux/wait,h>中,可通过静态定义并初始化一个等待队列头:
DECLARE_WAIT_QUENE_HEAD(name);
define DECLARE_WAIT_QUEUE_HEAD(name) \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
或者使用动态方法:
wait_quene_head_t my_quene;
init_waitquene_head (&my_quene);
void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *key)
{
spin_lock_init(&q->lock);
lockdep_set_class(&q->lock, key);
INIT_LIST_HEAD(&q->task_list);
} typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
spinlock_t lock;
struct list_head task_list;
};<1>、简单休眠#define wait_event(wq, condition) \
do { \
if (condition) \
break; \
__wait_event(wq, condition); \
} while (0)
#define wait_event_timeout(wq, condition, timeout) \
({ \
long __ret = timeout; \
if (!(condition)) \
__wait_event_timeout(wq, condition, __ret); \
__ret; \
})
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
#define wait_event_interruptible_timeout(wq, condition, timeout) \
({ \
long __ret = timeout; \
if (!(condition)) \
__wait_event_interruptible_timeout(wq, condition, __ret); \
__ret; \
})
<2>唤醒休眠wake_up()
#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL)#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
本文探讨了Linux字符设备驱动程序中休眠机制的重要性,包括如何安全地进入休眠状态,以及如何唤醒已休眠的进程。重点介绍了等待队列的使用,以及如何实现简单休眠、唤醒休眠等操作。
413

被折叠的 条评论
为什么被折叠?



