Linux的同步和异步

一.并发控制
(1)自旋锁
得不到资源,会原地打转,直到获得资源为止
定义自旋锁
[html]  view plain  copy
  1. spinlock_t spin;  
初始化自旋锁
[html]  view plain  copy
  1. spin_lock_init(lock);  
获得自旋锁
[html]  view plain  copy
  1. <span style="white-space:pre;"> </span>spin_lock(lock);获得自旋锁,如果能立即获得,则马上返回,否则自旋在那里,直到该自旋锁的保持者释放  
  2.     spin_trylock(lock);尝试获得自旋锁,如果能立即获得,它获得并返回真,否则  
  3. 立即返回假,实际上,不再“在原地打转”  
       释放自旋锁
[html]  view plain  copy
  1. <span style="white-space:pre;"> </span>spin_unlock(lock);与spin_trylock或者spin_lock配对使用  
使用方法:
[html]  view plain  copy
  1. spinlock_t lock;  
  2. spin_lock_init(&lock);  
  3.   
  4. spin_lock(&lock);//获取自旋锁,保护临界区  
  5. ...//临界区  
  6. spin_unlock(&lock);//解锁    

eg:使用自旋锁使设备只能被一个进程打开
[html]  view plain  copy
  1. int xxx_count=0;  
  2. static int xxx_open(struct inode *inode, struct file *filp)  
  3. {  
  4.     ...  
  5.     spinlock(&xxx_lock);  
  6.     if(xxx_count)  
  7.     {  
  8.         spin_unlock(&xxx_lock);  
  9.         return -EBUSY;  
  10.     }  
  11.     xxx_count++;  
  12.     spin_unlock(&xxx_lock);  
  13.     ...  
  14.     return 0;  
  15. }                  
  16. static int xxx_release(struct inode *inode,struct file *filp)  
  17. {  
  18.     ...  
  19.     spinlock(&xxx_lock);  
  20.     xxx_count--;  
  21.     spin_unlock(&xxx_lock);  
  22.       
  23.     return 0;  
  24. }      
(2)信号量
得不到资源,会进入休眠状态   
定义信号量
[html]  view plain  copy
  1. struct semaphore sem;  
初始化信号量
[html]  view plain  copy
  1. void sema_init(struct semaphore *sem,int val);初始化并设置为val  
  2. void init_MUTEX(struct semaphore *sem);初始化并设置为1  
  3. void init_MUTEX_LOCKED(struct semaphore *sem);初始化并设置为0  
下面两个宏用于定义并初始化信号量的“快捷方式”
[html]  view plain  copy
  1. DECLARE_MUTEX(name);初始化并设置为1  
  2. DECLARE_MUTEX_LOCKED(name);初始化并设置为0                                         获得信号量  
  3. void down(struct semaphore *sem);会导致休眠,不能在中断上下文使用  
  4. int down_interruptible(struct semaphore *sem);不会导致休眠,可在中断上下文使用  
使用down_interruptible()获得信号量时,常对返回值进行检查
[html]  view plain  copy
  1. if(down_interruptible(&sem))  
  2. {  
  3.     return -ERESTARTSYS;  
  4. }                        
释放信号量
[html]  view plain  copy
  1. void up(struct semaphore *sem);释放信号量sem,唤醒等待者  
使用方法:
[html]  view plain  copy
  1. DECLARE_MUTEX(mount_sem);  
  2. down(&mount_sem);获取信号量,保护临界区  
  3. ...  
  4. critical section //临界区  
  5. ...  
  6. up(&mount_sem);//释放信号量  
eg:使用信号量实现设备只能被一个进程打开
[html]  view plain  copy
  1. static DECLARE_MUTEX(xxx_lock);//定义互斥锁  
  2. static int xxx_open(struct inode *inode,struct file *filp)  
  3. {  
  4.     ...  
  5.     if(down_trylock(&xxx_lock))//获得打开锁  
  6.         return -EBUSY;//设备忙  
  7.     ...  
  8.     return 0;  
  9. }                  
  10. static int xxx_release(struct inode *inode,struct file *filp)  
  11. {  
  12.     up(&xxx_lock);//释放打开锁  
  13.     return 0;  
  14. }                  
总结:在多CPU中需要自旋锁来互斥,当进程占用资源时间较长,使用信号量。当所要保护的临界区访问时间较短,用自旋锁,它节省了上下文切换的时间。
     信号量所保护的临界区可包含可能引起阻塞的代码,自旋锁不能包含。阻塞意味着进行进程的切换,如果进程被切换出去后,另一个进程企图获取本自旋锁,死锁会发生。
     信号量存在进程上下文,如果被保护的共享资源需要在中断或软中断情况下使用,只能使用自旋锁,如果一定要使用信号量,只能通过down_trylock()方式进行,不能获取就立即返回避免阻塞。
     自旋锁会导致死循环,锁定期间不允许阻塞,锁定的临界区要小。
(3)互斥体
信号量已经可以实现互斥的功能,但是mutex还是在linux中真实存在
定义并初始化
[html]  view plain  copy
  1. struct mutex my_mutex;  
  2. mutex_init(&my_mutex);  
获取互斥体
[html]  view plain  copy
  1. void fastcall mutex_lock(struct mutex *lock);  
  2. int fastcall mutex_lock_interruptible(strutct mutex *lock);  
  3. int fastcall mutex_trylock(struct mutex *lock);  
释放互斥体
[html]  view plain  copy
  1. void fastcall mutex_unlock(struct mutex *lock);  
使用方法
[html]  view plain  copy
  1. struct mutex my_mutex;  
  2. mutex_init(&my_mutex);  
  3.   
  4. mutex_lock(&my_mutex);  
  5. ...//临界资源  
  6. mutex_unlock(&my_mutex);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值