字符设备驱动程序学习笔记四

竟争与互斥


程序调试
1 打印调试信息 printk
定义全局打印
示例代码如下:
#ifdef PDEBUG
#define PLOG(fmt,args...) printk(KERN_DEBUG "scull:",fmt,##args)
#else
/*do nothing*/
#define PLOG(fmt,args...)
#endif


在makefile中定义PDEBUG的值
示例代码如下:
DEBUG=y
ifeq($(DEBUG),y)
DEBFLAGS=-O2 -g -D PDEBUG
else
DEBFLAGS=-O2
endif
cflags+=$(DEBFLAGS)



2 调试器调试 kdb kgdb
3 查询调试
4 通过内核配置工具中的kernel hacking菜单
5 通过监视调试strace



并发与竟态
并发: 多个执行单元同时被执行
竞态:并发的执行单元对共享资源的访问导致的竞争状态


示例代码如下:
if(copy_from_user(&dev->data[pos]),buf,count)
ret=-EFAULT;
goto out;




加锁 互斥


spin_lock机制
semaphore机制


信号量
如果一个任务相要获得已经被占用的信号量时,信号量将会将这个进程放入一个


等待队列,然后让其睡眠,当持有信号量的进程将信号释放后,处于等待队列中


的任务被子唤醒


在<asm/semaphore.h>定义
定义信号量
struct semaphore sem;
初始人信号量
/*设置信号量的初值为val*/
void sema_init(struct semaphore *sem,int val)






互斥体必须在运行时被初始化
/*初始化一个互斥锁,把sem的值设为1 */
void init_MUTE(struct semphore *sem)
/*同上,将sem设置为0,为已锁状态*/
void init_MUTEX_LOCKED(struct semaphore *sem)




/*定义初始化为1*/
DECLARE_MUTEX(name)
/*定义初如化为0*/
DECLARE_MUTEX_LOCKED(name)


获取信号量
/*不建议使用,可能会导致程序睡眠,不能在中断上下文使用该函数*/
void down(struct semaphore *sem)
/*如果信号量不可用,进程将被置为TASK_INTERRUPTIBLE*/
int down_interruptible(struct semaphore *sem)
/*如果信号量不可用,置为TASK_KILLABLE*/
down_killable(struct semaphore *sem)






释放信号量
/*把sem的值加1,如果sem的值为非正数,表明有任务等待,唤醒这些等待者*/
void up(struct semaphore *sem)




自旋锁
最多只能被一个可执行单元持有,不会引起调用者睡眠
如果一个执行线程想要获得一个已经被持有的自旋锁,就会一直进行忙循环,查


看是否被释放


/*初始化自旋锁*/
spin_lock_init(x)
/*获取自旋锁,不成功则一直自旋在那里*/
spin_lock(lock)
/*获取自旋锁,直接返回真假,不会一直等待*/
spin_trylock(lock)
/*释放自旋锁*/
spin_unlock(lock)










自旋锁与信号量的使用场景


自旋锁 只有一个持有者
时间较短的情况


信号量 多个持有者
保持时间较长的情况

猜你喜欢

转载自retacn-yue.iteye.com/blog/1859867