前些天开发了一个程序,主要功能是控制多个进程对一个软件锁的读取/写入访问操作,保证多个进程同时启动,读软件锁的访问不能冲突,造成死锁等问题。
采用的方法是使用CSingleLock建立全局的进程锁,对各个进程对软件锁的读取进行控制。
感到其中最重要的是如何确定每次用进程锁锁定的代码范围,以及每次对软件锁操作的数据粒度的划分。
1:避免嵌套锁定范围。造成的做要原因是每个对软件锁的操作的函数A,B,。。。都用CSingleLock将操作代码锁定,但是当一个函数A调用另一函数B时,由于二者都锁定了操作代码造成锁嵌套。
2:对软件锁的数据读写粒度划分:每次操作的数据应为独立数据单元。粒度过小时易造成要通过多次读取软件锁得到几个数据元素,并且只有将这几个数据元素合成后才有意义,特别是这几个数据元素的操作之间是不能被打断,必须连续的。这中国情况下由于是多个进程对软件狗争夺式操作,一个进程A操作完读取了K数据段的几个数据单元,很可能立刻被另一个进程B夺取软件锁访问权也对数据段K进行操作,这时进程A再对软件锁操数据段K操作得到的数据单元很可能和该进程A上一次的到数据单元是不连续的,无意义的。造成一个进程A相邻的两次对软件锁的读取操作数据失去意义。
解决方法:
第一种情况:封装对软件锁的原子操作接口内(A)不进行CSingleLock控制,只在模块B调用调用A的接口时用CSingleLock进行代码锁定。
并且保证模块B内不调用B内的函数。
第二种情况:每次对软件锁的操作的数据粒度以一个完整的数据为单位。例如,时间可以由年/月/日/时/分/秒构成则每次软件锁读取时间或写入时间时以一个描述完整的时间的数据。即一次读出年月日时分秒,而不是如下流程:CSingleLock锁定代码,读出年,放开CSingleLock;CSingleLock锁定代码,再读取月,再放开CSingleLock;。。。。依次读出年月日时分秒,然后再将这几个数据组成由年月日时分秒构成的时间数据。
以上是个人的一点拙见,不足之处望赐教。