1.原子操作:指在执行过程中不会别的进程所中断的操作。
常用的原子操作函数:
atomic_t v=ATOMIC_INIT(0); //定义原子变量v并初始化为0
void atomic_read(atomic_t *v); //读取原子变量的值返回到v
void atomic_inc(atomic_t *v); //原子变量加1
void atomic_dec(atomic_t *v); //原子变量减1
int atomic_dec_and_test(atomic_t *v); //原子变量减1后测试是否为0,是则返回ture,否则返回false。
2.信号量:用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区的代码,当获取不到信号量时,进程进入休眠等待状态。
定义信号量:
struct semaphore sem;
初始化信号量:
void sema_init(struct semaphore *sem, int val);
void init_MUTEX(struct semaphore *sem); //初始化为0
static DECLARE_MUTEX(button_lock); //定义互斥锁
获取信号量
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem); //信号量已经被其他进程获取,则返回非零值
释放信号量:
void up(struct semaphore *sem);
3.阻塞:
阻塞指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被调度器从运行队列中移走,直到等待的条件被满足。
非阻塞指进程不能再进行设备操作时并不挂起,它或者放弃,或者不停地查询,直至可以进行操作为止。
fd=open("...", O_RDWR | O_NOBLOCK);
4.异步:
整体框架:
应用程序:注册信号处理函数
谁发:驱动程序发;
发给谁:应用程序指定,具体操作如下。
1). fcntl (fd, F_SETOWN, pid); //支持F_SETOWN命令,能在这个控制命令处理中设置file->f_owner为对应进程ID,此工作由内核完成,设备驱动无需处理。
2).oflags = fcntl(fd, F_GETFL);
fcntl (fd, F_SETFL, oflags | FASYNC) ; //支持F_SETFL命令的处理,每当FASYNC标志改变时,驱动程序中的fasync()函数将得以执行,驱动程序中应该实现fasync()函数。
怎么发:在设备资源可获得时, 调用kill_fasync()函数发送相应的信号给应用程序。kill_fasync(&button_async, SIGIO, POLL_IN); //button_async为struct fasync_struct *button_async