Linux多线程编程(二)-----同步与互斥

Linux多线程编程(一):http://blog.csdn.net/llzk_/article/details/55670172
由上篇博客我们可以知道,多个线程是共享同一份内存的。这就意味着这么多线程共享同一份数据资源。这时就很可能出现多个线程因竞争同一份资源而发生冲突的问题。就算从程序不挂掉,运行结果也不会太正确。
例如,现在有两个线程A,B分别要对一个数据a = 5执行加1操作。正常来说,a最后的值应该为7。
加1操作共分下面三步:

  1. 将数据从内存单元读入寄存器。
  2. 在寄存器中对变量做增量操作。
  3. 把新的值写回内存单元。

由于加1操作分三步进行, 并不是原子操作(要么不做,要么一次性完成)。所以这就为错误的出现提供了无限的可能。如下图:
这里写图片描述

当线程A正在执行第二步的时候,线程B切入,从内存读到了a的值为5。并执行了加1操作,最后内存中a的值是6,并不是我们想要的7。这与线程B切入的时间有关。
要想的到正确的结果,我们不得不为这些线程加一些限制,就是我们所谓的同步与互斥。

互斥

一份资源在一个时刻内只能被一个进程或线程访问。
比如现在有一个门。门外墙上只挂着一把钥匙。一次只有一个人可以拿着钥匙打开门进去。钥匙也一并被拿进去。此时门外的人只能等待。门内的资源在这段等待时间内只被门内的人一人占用。这就是所谓的互斥。

同步

进程按一定的顺序访问临界资源,同步强调的是协同,一般都在互斥的前提下,但在有些场景下也不需要互斥。
门外的人按照一定的规则按顺序拿钥匙进门就是同步。

互斥量

互斥量,也叫互斥锁。是我们实现同步重要工具。在线程访问共享资源前对互斥量进行设置(加锁),在线程访问共享资源结束后释放互斥量(解锁)。
通过加锁解锁,我们可以将原来的分多步的操作变成一个“原子”操作。系统只会在执行完“锁内”的代码后,才可能会被切去执行其他线程。这个“锁”,也可以理解为上文所描述的“钥匙”。在一个线程占用锁资源时(钥匙),任何其他再试图申请同一份锁资源的线程,都会被阻塞。直到当前线程释放该锁资源。正规来说,对互斥量进行加锁以后,任何其他试图再次对互斥量加锁的线程都会被阻塞,直到当前线程释放该互斥锁。
在互斥锁被释放时,所有因为该锁被阻塞的线程都会变成可运行状态,第一个变为运行的线程就可以对互斥量加锁(获取钥匙),其他线程就会看到锁资源依然被占用,只能回去再次等待。
在这种方式下,我们可以达

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值