Linux等待队列

多路IO复用select采用等待队列机制让用户程序没有资源读/写时睡眠,有资源读/写时唤醒用户程序。

等待队列以双向循环链表为基础数据结构,与进程调度紧密结合,用于实现内核的异步事件通知机制,也可用于同步对系统资源的访问。

1. 数据结构

(1) 每个等待队列都有一个等待队列头,该结构定义如下:

struct __wait_queue_head {
spinlock_t		lock;           //自旋锁,在对task_list操作时,使用该锁实现对等待队列的互斥访问
struct list_head	task_list;      // 双向循环链表
};

每次对等待队列的操作都需要加自旋锁,防止其他进程对等待队列的写操作,实现对等待队列的互斥访问,并且保证临界区的原子性。使用task_list连接一个等待队列项。

(2) 等待队列项,定义如下:

//等待队列项。每个等待任务都会抽象成为一个_wait_queue,并且挂载在__wait_queue_head
struct __wait_queue {
unsigned int		flags;       // 互斥/非互斥进程  
#define WQ_FLAG_EXCLUSIVE   0x01
void			*private;    // 指向一个task_struct实例
wait_queue_func_t	func;        // 函数指针,用于唤醒进程
struct list_head	task_list;  // 挂入__wait_queue_head
};
typedef struct __wait_queue_head wait_queue_head_t;
typedef struct __wait_queue wait_queue_t;

#define WQ_FLAG_EXCLUSIVE  0x01 互斥进程标志,private指向一个task_struct实例,每一个进程使用结构体task_struct来表示。Func是一个函数指针,声明如下:

typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);

该函数指针在唤醒进程函数__wake_up_common调用,func默认调用default_wake_function唤醒进程。使用task_list与__wait_queue_head连接。

2. 初始化

(1) 等待队列头初始化。

//初始化
#define DECLARE_WAIT_QUEUE_HEAD(name)                              \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
// 初始化未加锁
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {			   \
	.lock		= __SPIN
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值