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

竟争与互斥


程序调试
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)










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


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


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

你可能感兴趣的:(字符设备驱动程序学习笔记四)