Linux wait_queue_entry_t 实现 生产和消费

Linux wait_queue_entry_t 实现 生产和消费

关键代码

关键头文件结构体

#include <linux/wait.h>
#include <linux/spinlock.h>
//生产和消费公用的队列 最多缓存的个数
#define BUFFER_SIZE 100 
struct buffer {
	int data[BUFFER_SIZE];//生产和消费的 数据,也可以是结构体  
	int count;			  //队列缓存个数的统计
	int head;
	int tail;
	wait_queue_head_t not_empty;
	wait_queue_head_t not_full;
	spinlock_t lock;  
};

struct buffer my_buffer;

// 初始化缓冲区(在生产和消费之前必须初始化)  
void init_buffer(struct buffer *buf) {
	buf->head = buf->tail = 0;
	buf->count = 0;
	spin_lock_init(&buf->lock);
	init_waitqueue_head(&buf->not_empty);
	init_waitqueue_head(&buf->not_full);  
}

生产者函数

/*
@ buf 生产和消费的公共buf
@ value 为生产者生产的数据
*/
void producer(struct buffer *buf, int value) {
	unsigned long flags;
	wait_queue_entry_t wait;
	spin_lock_irqsave(&buf->lock, flags);
	while (buf->count == BUFFER_SIZE) {
		// 缓冲区满,生产者等待
		init_waitqueue_entry(&wait, current);
		add_wait_queue(&buf->not_full, &wait);
		// 释放锁并睡眠
		spin_unlock_irqrestore(&buf->lock, flags);
		// 等待被唤醒
		schedule();
		// 重新获取锁  
        spin_lock_irqsave(&buf->lock, flags);
        // 从等待队列中移除
        remove_wait_queue(&buf->not_full, &wait);
      }
     // 向缓冲区添加数据
     buf->data[buf->tail] = value;
     //buf->tail = (buf->tail + 1) % BUFFER_SIZE;
     buf->tail = buf->tail + 1;
     buf->count++;
     // 唤醒等待的消费者
     wake_up(&buf->not_empty);
     spin_unlock_irqrestore(&buf->lock, flags);
}

消费者函数

/*
@ buf 生产和消费的公共buf
@ 返回为消费者需要获取到的数据
*/
int consumer(struct buffer *buf) {
	unsigned long flags;
	wait_queue_entry_t wait;
	int value;
	spin_lock_irqsave(&buf->lock, flags);
	while (buf->count == 0) {
		// 缓冲区空,消费者等待
		init_waitqueue_entry(&wait, current);
		add_wait_queue(&buf->not_empty, &wait);
		// 释放锁并睡眠
		spin_unlock_irqrestore(&buf->lock, flags);
		// 等待被唤醒
		schedule();
		// 重新获取锁
		spin_lock_irqsave(&buf->lock, flags);
		// 从等待队列中移除
		remove_wait_queue(&buf->not_empty, &wait);
	}
	// 从缓冲区取出数据
	value = buf->data[buf->head];
	buf->head = (buf->head + 1) % BUFFER_SIZE;
	buf->count--;
	// 唤醒等待的生产者
	wake_up(&buf->not_full);
	spin_unlock_irqrestore(&buf->lock, flags);
	return value;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值