加入收藏 | 设为首页 | 会员中心 | 我要投稿 3v站长网 (https://www.3vvv.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 系统 > 正文

一文读取Linux延时队列工作原理

发布时间:2021-10-20 13:32:29 所属栏目:系统 来源:互联网
导读:要使用 waitqueue 首先需要声明一个 wait_queue_head_t 结构的变量,wait_queue_head_t 结构定义如下: struct __wait_queue_head { spinlock_t lock; struct list_head task_list; }; waitqueue 本质上是一个链表,而 wait_queue_head_t 结构是 waitqueue
要使用 waitqueue 首先需要声明一个 wait_queue_head_t 结构的变量,wait_queue_head_t 结构定义如下:
 
struct __wait_queue_head { 
    spinlock_t lock; 
    struct list_head task_list; 
}; 
waitqueue 本质上是一个链表,而 wait_queue_head_t 结构是 waitqueue 的头部,lock 字段用于保护等待队列在多核环境下数据被破坏,而 task_list 字段用于保存等待资源的进程列表。
 
可以通过调用 init_waitqueue_head() 函数来初始化 wait_queue_head_t 结构,其实现如下:
 
void init_waitqueue_head(wait_queue_head_t *q) 
    spin_lock_init(&q->lock); 
    INIT_LIST_HEAD(&q->task_list); 
初始化过程很简单,首先调用 spin_lock_init() 来初始化自旋锁 lock,然后调用 INIT_LIST_HEAD() 来初始化进程链表。
 
向等待队列添加等待进程
要向 waitqueue 添加等待进程,首先要声明一个 wait_queue_t 结构的变量,wait_queue_t 结构定义如下:
 
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key); 
 
struct __wait_queue { 
    unsigned int flags; 
    void *private; 
    wait_queue_func_t func; 
    struct list_head task_list; 
}; 
下面说明一下各个成员的作用:
 
flags: 可以设置为 WQ_FLAG_EXCLUSIVE,表示等待的进程应该独占资源(解决惊群现象)。
 
private: 一般用于保存等待进程的进程描述符 task_struct。
 
func: 唤醒函数,一般设置为 default_wake_function() 函数,当然也可以设置为自定义的唤醒函数。
 
task_list: 用于连接其他等待资源的进程。
 
可以通过调用 init_waitqueue_entry() 函数来初始化 wait_queue_t 结构变量,其实现如下:
 
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p) 
    q->flags = 0; 
    q->private = p; 
    q->func = default_wake_function; 
也可以通过调用 init_waitqueue_func_entry() 函数来初始化为自定义的唤醒函数:
 
static inline void init_waitqueue_func_entry(wait_queue_t *q, wait_queue_func_t func) 
    q->flags = 0; 
    q->private = NULL; 
    q->func = func; 
初始化完 wait_queue_t 结构变量后,可以通过调用 add_wait_queue() 函数把等待进程添加到等待队列,其实现如下:
 
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) 
    unsigned long flags; 
 
    wait->flags &= ~WQ_FLAG_EXCLUSIVE; 
    spin_lock_irqsave(&q->lock, flags); 
    __add_wait_queue(q, wait); 
    spin_unlock_irqrestore(&q->lock, flags); 
 
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) 
    list_add(&new->task_list, &head->task_list); 
add_wait_queue() 函数的实现很简单,首先通过调用 spin_lock_irqsave() 上锁,然后调用 list_add() 函数把节点添加到等待队列即可。

(编辑:3v站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读