第五章:并发与竞态

两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,就成为竞争条件(race condition)。
竟态通常作为对资源的共享访问结果而产生的。当两个或多个进程需要访问相同的数据结构(或硬件资源)时,混合的可能性就永远存在。 因此在自己设计驱动程序的时候,第一个要记住的规则是, 只要可能,就应该避免资源共享。如果没有并发的访问,也就不会有竟态的产生。 因此, 仔细编写的内核代码应该具有最少的共享。这种思想的最明显应用就是避免使用全局变量。如果我们将资源放在一个多个执行线程都会找到的地方,则必须有足够的理由。

资源共享的硬规则:在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,因此必须显式地管理对该资源的访问。

访问管理的常见技术成为“锁定”或者“互斥” ——确保一次只有一个执行线程可操作共享资源。


信号量
创建信号量:
   
   
  1. void sema_init(struct semaphore *sem, int val); //val 是赋予一个信号量的初始值
不过,信号量通常被用于互斥模式。为了让这种常见情况更加简单,内核提供了辅助函数和宏
   
   
  1. DECLARE_MUTEX(name);
  2. DECLARE_MUTEX_LOCKED(name);
 第一种是定义一个信号量变量name,并被初始化为1。
第二种是定义一个信号量变量name,并被初始化为0,而且互斥锁的初始状态是锁定的。

如果互斥体必须在 运行时被初始化(例如在动态分配互斥体的情况),应使用下面的函数之一:
   
   
  1. void init_MUTEX(struct semaphore *sem);
  2. void init_MUTEX_LOCKED(struct demaphore *sem);

down的三个版本:
   
   
  1. void down(struct semaphore *sem);
  2. int down_interruptible(struct semaphore *sem);
  3. int down_trylock(struct semaphore *sem);
down减小信号量的值,并在必要时一直等待。
down_interruptible完成相同的工作,但操作是可中断的。可中断的版本几乎使我们始终要用的版本,它允许等待在某个信号量上的用户空间进程可被用户中断。但是在使用down_interruptible需要额外小心,如果操作被中断,该函数会返回非零值,而调用者不会拥有该信号量。对down_interruptible的正确使用需要始终检查返回值,并作出相应的响应。
down_try_lock永远不会休眠;如果信号量在调用时不可获得,down_trylock会立即返回一个非零值。

成功调用down函数后,就称为该线程拥有了该信号量。这样该线程就被赋予了访问由该信号量保护的临界区的权利。

up函数
   
   
  1. void up(struct semaphore *sem);
调用up后,该线程就不再拥有该信号量。

down和up都是成对的调用的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值