遇到一个两个进程同时访问一个软件狗,产生死锁。具体场景如下:两个进程(A,B)都产生一个后台线程对软件狗进行管理,并且使用的是同一个接口类的不同对象,该接口类的建立采用了singlton模式。
1:一个进程启动后,对软件锁进行扫描,判断其可用性,记录其句柄,并打开。
2:启动另一个进程,同样对软件锁进行扫描,判断其可用性,并记录句柄,并打开。
3:第二个进程不能启动。一直处于停滞状态。
排除......过程结果补充如下。
经过多方尝试,终于解决了。
主要经过如下:
1:一开始怀疑是singlton的作用范围是跨进程的,结论。singlton变量的作用范围是在其所属进程范围内的。不能跨进程。
2:制作测试例子原型。通过制作两个使用使用同一个软件锁的原型工程 来测试使用软件锁的使用方法。这两个原型中去掉了singlton的构建方式。
结果仍然死锁。
3:通过多处打断点,提示警告框,发现,原来用于锁定资源变量的进程互斥量没有成对使用。修改该互斥量的锁定资源,释放资源成对使用后。运行。
原本以为万事大吉,但是。
但当测试时,A和第三方软件的进程C同时启动运行,时A启动正确,但运行一段时间 A提示读取软件锁错误。并且时间不定。
由于没有第三方C的进程源码,不好判断错误原因。对A的源码进行断点追踪,发现AC启动后刚开始A读取软件锁正确,但过一会A读取软件狗错误。
这时依稀记得看过C的软件锁的使用方式,C的软件狗使用方法中,每次使用时打开软件锁,用完关闭。(由于认为这样使用费时所以当时没采用)
推测,C使用软件狗方法的方法有问题,并且而A的读写错误的提示信息是没有找到指定的文件,该文件是放在根目录下的。
可能是C进入软件狗的子目录后执行完毕,没有回到根目录。当C都对软件狗进行操作后,A自然警告错误。
这是回想起并且当初就是因为A和C同时启动时出现以上冲突,才将A的软件锁互斥量不成对使用,当时避免了冲突问题,还以为问题真正解决了,但现在看来,当时只是A一种假象。
A修改软件锁使用方法,每次执行时才打开,用完关闭。
测试成功
再次测试,还是发生偶尔冲突,造成软件锁读写错误。经过跟踪仍然是开始对,过一会读写错误。
经过查询,发现是互斥量的作用范围过小,造成有可能软件锁在两次互斥量的作用范围外也有肯能被C进程对软件锁操作,从而造成第二次对软件锁读取时,造成读取错误。
扩大互斥量的作用范围。编译测试。正常。
收获:
1:任何问题都有原因,没有找到根源就不算解决问题。哪怕一时蒙混过关,也是错误的,早晚会遭到报应。正是不是不报,时机未到。
2: 不要随意怀疑是他人的原因造成自己的程序的错误,先找自己的原因。比如怀疑互斥量的使用方法必须成对使用。可笑。
3:简单的使用方法可以产生有效的效果,不要盲目追求复杂。
4:对于不同的共享资源类型要根据实际具体情况对待。
虽然在一些多进程编程建议对共享资源使用互斥量时作用范围尽量小,使用完马上释放。
但对于软件锁这类进程/线程的共享资源的使用方式。释放互斥量应在一个使用周期完的一系列操作后释放比较好。
以上为实际情况,以及分析,权当抛砖引玉。