volatile 与诡异事件

  下面是我遇到的一个多线程程序中诡异事件的解决过程:主线程main启动 thread1 和 thread2,thread2保持阻塞,接到thread1发出的信号后工作,完毕后发出终了信号通知thread1,再次阻塞...直到thread1发出结束信号为止。代码如下:(信号用全局变量实现)
thread.h

 

thread.c



thread1.c


thread2.c

 

编译:
#gcc -o Thread thread.c thread1.c thread2.c -pthread
运行,正常结果是(指的是不会卡住,某些步骤会有先后变化)
#./Thread
thread1---thread1 start
thread1---send_task: 1
thread2---thread2 start
thread2---hanging and waiting...
thread2---got task: 1
thread2---Haahahhahahah!~
thread2---hanging and waiting...
thread1---send_task: 2
thread2---got task: 2
thread2---OhhAhhhOhhhhh!~
thread2---hanging and waiting...
thread1---send_task: 3
thread2---got task: 3
thread2---I'm dying...!~
thread2---thread2 over
thread1---thread1 over
Thread 1 returns: 0
Thread 2 returns: 0


但是结果多变,常常卡在


(thread2 运行越慢,越易重现,所以我故意在thread2.c 内加入 sleep(3);)
   程序逻辑没问题,不存在死锁,为什么会卡在上面两步?明明 task_ready 已由 thread2 修改过了,thread1的这个语句
为什么”不知道“?为什么一个线程察觉不到别的线程对公共全局变量的修改?这时候,忽然想到了一个从未用过的很奇特的限定符(qualifier)volatile:通知编译器,即使当前的程序(进程/线程)未修改它所标识的变量,此变量值也会改变。(可能其他程序/线程/硬件修改这个变量)。
为什么需要通知?先看看一句代码的汇编实现:(是用ARM实现的,我的机器是AMD64的,这两句没产生优化)


   因为,有时,编译器会对频繁使用的变量或者它认为“不会改变”的变量进行优化,对变量取值时不是从每次从内存-->寄存器;
而是直接一次取出保存在寄存器内,以后直接从寄存器取。问题就在于此:"似乎"不会改变的 task_ready和 main_task会被
thread2所修改,此处的“优化”就是问题所在,解决方式就是相关变量加上volatile即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值