等待队列
什么是等待队列
等待队列是内核实现阻塞和唤醒的内核机制。等待队列以循环链表为基础结构,链表头和链表项分别为等待队列头和等待队列元素。整个等待队列由等待队列头进行管理。
等待队列头使用结构体 wait_queue _head_t来表示, 等待队列头就是一个等待队列的头部,这个结构体定义在文件include/linux/wait.h里面,结构体内容如下:
struct wait queue head {
spinlock_t lock; //自旋锁
struct list_head task_list; //链表头
}
typedef struct wait_queue_head wait_queue_head_t;
定义并初始化等待队列头
方法一:
(1) 定义一个等待队列头:
wait_queue head t test_wq; //定义一个等待队列的头
初始化等待队列头:
(2)
可以使用 init waitqueue head 函数初始化等待队列头,函数原型如下:
方法二:
使用宏 DECLARE_WAIT_QUEUE_HEAD 来一次性完成等待队列头的定义和初始化。
原型:
DECLARE_WAIT_QUEUE_HEAD(wait_queue_head_t q);
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#define DEVICE_NAME "poll_dev"
#define CLASS_NAME "poll_class"
/*初始化一个队列头*/
static DECLARE_WAIT_QUEUE_HEAD(read_wq);
static struct class *char_class;
static struct device *char_device;
int major;
int flag = 0;
char mes_buf[30];
int hello_open (struct inode *inode, struct file *file){
pr_info("hello_open\n");
return 0;
}
ssize_t hello_read(struct file *file, char __user *buf, size_t size, loff_t * loff_t){
if(file->f_flags & O_NONBLOCK){
if(flag == 0)
return -EAGAIN;
}
/*进入休眠状态*/
wait_event_interruptible(read_wq, flag);
if(copy_to_user(buf, mes_buf, strlen(mes_buf)) != 0)
return -EFAULT;
return strlen(mes_buf);
}
ssize_t hello_write (struct file *file, const char __user *buf, size_t size, loff_t *loff_t){
if(copy_from_user(mes_buf, buf, size) != 0){
printk(KERN_INFO "hello_write: copy_from_user error\n");
return -EFAULT;
}
printk(KERN_INFO "hello_write: %s\n", mes_buf);
/*设置条件后,唤醒休眠任务*/
flag = 1;
wake_up_interruptible(&read_wq);
return size;
}
int hello_close(struct inode *inode, struct file *file){
printk(KERN_INFO "hello_close\n");
return 0;
}
static struct file_operations file_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_close,
.read = hello_read,
.write = hello_write,
};
static int __init hello_init(void){
major = register_chrdev(0, DEVICE_NAME, &file_fops);
if(major < 0){
printk("key_irq_init register_chrdev failed\n");
return major;
}
char_class = class_create(THIS_MODULE, CLASS_NAME);
if(IS_ERR(char_class)){
unregister_chrdev(major, DEVICE_NAME);
printk("key_irq_init class_create failed\n");
return PTR_ERR(char_class);
}
char_device = device_create(char_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
if(IS_ERR(char_device)){
class_destroy(char_class);
unregister_chrdev(major, DEVICE_NAME);
printk("key_irq_init device_create failed\n");
return PTR_ERR(char_device);
}
printk("key_irq_init success\n");
return 0;
}
static void __exit hello_exit(void){
unregister_chrdev(major, DEVICE_NAME);
device_destroy(char_class, MKDEV(major, 0));
class_destroy(char_class);
printk("key_irq_exit success\n");
}
module_init(hello_init); /*指定设备驱动入口函数*/
module_exit(hello_exit); /*指定设备驱动出口函数*/
MODULE_LICENSE("GPL");
标签:struct,队列,class,char,include,等待,hello
From: https://www.cnblogs.com/zxz-FINE/p/17914053.html