设为首页 收藏本站
查看: 296|回复: 0

[经验分享] Linux下线程的同步与互斥

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2016-4-22 10:43:20 | 显示全部楼层 |阅读模式
一、线程的互斥
  多个线程同时访问共享数据时可能会冲突,跟之前信号量的可重如性是同样的问题。如两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成:  

1. 从内存读变量值到寄存器
2. 寄存器的值加1
3. 将寄存器的值写回内存
如下程序就会产生问题:
wKioL1cYcNPwkXzTAAB71wjpvMI523.jpg
我们创建两个线程,每把g_count增加5000次,正常情况下最后g_count应该等于10000,但事实上每次运行该程序的结果都不一样。
wKiom1cYckeDoNUPAAAKWUPo5ek398.jpg
  对于多线程的程序,访问冲突的问题是很普遍的,解决的办法是引入互斥锁(Mutex,Mutual Exclusive Lock),获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程,没有获得锁的线程只能等待而不能访问共享数据,这样“读-修改-写”三步操作组成一个原子操作,要么都执行,要么都不执行,不会执行到中间被打断,也不会在其它处理器上并行做这个操作。
Mutex用pthread_mutex_t类型的变量表示,可以这样创建和初始化

wKioL1cYcR3jZY4VAAA_wdEBIm8168.jpg
返回值:成功返回0,失败返回错误号。  
把以上程序加锁后:
wKiom1cYcWOh_g-FAACUsR9Stbk021.jpg
运行结果:
wKioL1cYclHwjvv0AAAM8bInLwY132.jpg
      为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性,即使是多处理器平台,访问内存的总线周期也有先后,一个处理器上的交换指令执行时另一个处理器的交换指令只能等待总线周期。
lock:
        movb $0,%al

        xchgb &a1,mutex

        if(a1寄存器的内容>0){
                return 0;
        }else
                挂起等待;

        goto lock;

unlock:   
        movb $1,mutex

        唤醒等待mutex的线程;

        return 0;

二、线程的同步

  线程的同步建立在互斥的基础之上,通常具有顺序性。当两个或多个线程互斥的访问一临界资源的时候,可能会引起死锁的现象。也可能会因为一直在竞争资源,都无法推进的情况。因此就需要线程间的同步。
线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。在pthread库中通过条件变量(Condition Variable)来阻塞等待某个条件,或者唤醒等待这个条件的线程。Condition Variablepthread_cond_t类型的变量表,可以这样初始化和销毁:
wKioL1cYeM2whfMMAAA72IoCNxU075.jpg
返回值:成功返回0,失败返回错误号。
一个Condition Variable总是和一个Mutex搭配使用的。一个线程可以调用pthread_cond_wait在一个Condition Variable上阻塞等待,这个函数做以下三步操作:
1. 释放Mutex
2. 阻塞等待
3. 当被唤醒时,重新获得Mutex并返回  
pthread_cond_timedwait函数还有一个额外的参数可以设定等待超时,如果到达了abstime所指定的时刻仍然没有别的线程来唤醒当前线程,就返回ETIMEDOUT。一个线程可以调用pthread_cond_signal唤醒在某个Condition Variable上等待的另一个线程,也可以调用pthread_cond_broadcast唤醒在这Condition Variable上等待的所有线程。
例如如下程序:
wKioL1cYfPriA33_AAB4bNLoyrA856.jpg
wKiom1cYfDjzYi22AACBL_BZlUs196.jpg
运行结果:
wKiom1cYfDmjhKJpAAAY7qQXYxw333.jpg
当pthread1不满足g_count的值大于等于20时就会执行上边pthread_cond_wait函数的三步操作:
1. 释放Mutex
2. 阻塞等待
3. 当被唤醒时,重新获得Mutex并返回
所以此时pthread2就会先执行,当满足g_count的值大于或等于20时pthread2才会被唤醒并获得互斥锁并执行。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-207309-1-1.html 上篇帖子: ubuntu zip 文件乱码解决压缩乱码 下篇帖子: 利用iptable limit模块限制ip下载速度 Linux
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表