一、原子操作
加入原子操作的目的就是多个
应用程序同时调用驱动程序, 原子操作的特性是在自增、自减等操作过程中不会被打断,防止两个应用程序同时调用驱动程序情况的发生,其使用过程如下:
static atomic_t canopen = ATOMIC_INIT(1); //定义原子变量并初始化为1
然后在XXX_open( )函数中这样初始化。
static int sixth_drv_open(struct inode *inode, struct file *file)
{
if (!atomic_dec_and_test(&canopen))
{
atomic_inc(&canopen);
return -EBUSY;
}
............
}
当原子量自减一次后,检测其为0时返回ture,此时不会进入if中。当不为0时会进入if中,返回-EBUSY,表示资源不可用。
二、信号量
这个比原子操作更加简单了,信号量(semaphore)是用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区代码。
当获取不到信号量时,进程进入休眠等待状态。
首先要定义一个互斥锁 static DECLARE_MUTEX(button_lock); //定义互斥锁
然后在xxx_open( )中获取信号量 down(&button_lock);
第一次调用xxx_open()时,会获得这个信号量,第二次调用时,就不会获得信号量了,会一直陷入休眠的状态。
在xxx_close( )中释放信号量 up(&button_lock);
三、阻塞
是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。
被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。直接分析代码:
这是xxx_open( )函数中的代码:
-
if (file->f_flags & O_NONBLOCK)
-
{
-
if (down_trylock(&button_lock))
-
return -EBUSY;
-
}
-
else
-
{
-
/* 获取信号量 */
-
down(&button_lock);
-
}
其中O_NONBLOCK 是非阻塞的一个标志,也就是当文件以非阻塞方式打开时,如果阻塞,直接返回-1;
但是当以阻塞方式打开时,会获取信号量;
以下时xxx_read( )中的代码:
-
if (file->f_flags & O_NONBLOCK)
-
{
-
if (!ev_press)
-
return -EAGAIN;
-
}
-
else
-
{
-
/* 如果没有按键动作, 休眠 */
-
wait_event_interruptible(button_waitq, ev_press);
-
}
当非阻塞方式打开时,如果没有中断发生,则直接返回-1;
当以阻塞方式打开时,如果有没有按键动作,就休眠了;
阅读(2856) | 评论(0) | 转发(0) |