Linux中等待队列的相关API

本文详细介绍了Linux内核中的等待队列概念与实现方法,包括等待队列的定义、初始化、添加与移除操作,以及如何通过等待队列实现进程间的同步与通信。此外,还提供了具体的代码实例来说明等待队列的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



1,等待队列
  1)定义等待队列头

   wait_queue_head_t my_queue;


  2)初始化
  init_waitqueue_head(&my_queue);
  //定义并初始化宏
  DECLEAR_WAIT_QUEUE_HEAD(name);

  DECLEAR_WAITQUEUE(name,tsk);//此定义宏中的参数 不需要事先自己定义


  3)添加、移除等待队列
  void fastcall add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);

  void fastcall remove_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);


  4)等待事件
  wait_event(queue,condition);
  wait_event_interruptible(queue,condition);
  wait_event_timeout(queue,condition);
  wait_event_interruptible_timeout(queue,condition);
  //等待第一个参数queue作为等待队列头的等待队列被唤醒,且第二个参数

  condition必须满足,否则阻塞


  5)唤醒队列
  void wake_up(wait_queue_head_t *queue);
  void wake_up_interruptible(wait_queue_head_t *queue);
  //上述操作会唤醒以queue作为等待队列头的所有等待队列中所有属于该等
  带队列头的等待队列对应的进程
  注意:wake_up()应该与wait_event()或wait_event_timeout()成对使用

interruptible也是成对使用。


  6)等待队列上的睡眠
  sleep_on(wait_queue_head_t *q);
  interruptible_sleep_on(wait_queue_head_t *q);
  //sleep_on()函数的作用就是将目前进程的状态置为TASK_UNINTERRUPTIBLE
  并定义一个等待队列,之后把它附属到等待队列q,直到资源可获得,q引导

  的等待队列被唤醒。sleep_on()与wake_up()应成对使用


等待队列的典型应用

struct glb {
	struct cdev cdev;
	unsigned int current_len;
	unsigned char mem[100];
	struct semaphore sem;
	wait_queue_head_t r_wait;
	// wait_queue_head_t w_wait;
};

size_t xxx_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
{
	struct glb *dev = filp->private_data;
	
	DECLEAR_WAITQUEUE(wait,current);// 定义等待队列
	
	down(&dev->sem);
	
	add_wait_queue(&dev->r_wait,&wait);//进入读的等待队列
	
	if(dev->current_len == 0){
		if(filp->f_flags & O_NONBLOCK){//非阻塞访问
			ret = -EAGAIN;
			goto out;
		}
		
		__set_current_state(TASK_INTERRUPTIBLE);//修改进程为睡眠
		
		up(&dev->sem);
		
		schedule();//调度其他进程
		
		if(signal_pending(current)){//如果信号唤醒
			ret = -ERESTARTSYS;
			goto out2;
		}
		down(&dev->sem);//重新获取信号量
	}
	if(count > dev->current_len)
		count = dev->current_len;
	if(copy_to_user(buf,dev->mem,count)){
		ret = -EFAULT;
		goto out;
	}else{
		memcpy(dev->mem,dev->mem+count,dev->current_len-count);
		//数据前移
		dev->count_len -= count;//有效数据减少
		wake_up_interruptible(&dev->w_wait);//唤醒写等待队列,注意:读队列的唤醒应该在xxx_write上执行,当写入了数据,说明可以读了
		ret = count;
	}
	
	//非阻塞及出错处理及程序结束处理
	out: up(&dev->sem);
	out2: remove_wait_queue(&dev->w_wait,&wait);
		  set_current_state(TASK_RUNNING);
		  return ret;
}




  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值