多进程同时访问文件并发问题解决方法

        因为业务需求需要多个进程同时访问某个文件并进行读写操作的需求,因为文件并不是被同一个进程访问,而且极大可能会发生多进程争抢文件句柄的情况,如果在同一个进程里不同的线程访问,或许还能使用线程锁的方式控制,但是跨进程时就无法解决。网上询问解决方法基本上都类似Linux里日志文件服务一样,建立一个独立的文件操作服务,由文件操作服务来控制不同进程对同一个文件的访问。但是这样改动量就比较大,而且因为不同的程序可能是由不同的语言编写的,比如JAVA和C#。而不同的语言访问window服务可能都有局限性(部署更是个大问题因为window服务需要最高的system权限运行),更重要的是如果一个程序需要平凡读写文件,每次读写前必须绕一层服务效率上大打折扣,所以此方法并未采纳。

        为了解决不同开发工具开发和效率所带来的问题,我不得不设计一种较简单实现,又不用太过修改代码的方法。参考vss想到,为什么不能在每次文件读写前先将文件签出?但是如何保证签出后的文件其他进程无法都写呢?一个方法是建立一个签出服务,这个不行原因前面已经提过。于是考虑最简单的方法,也就是每次读写文件前先改文件的扩展名。

        改扩展名的方法非常简单,也不难实现。现在程序访问文件前,都必须用原文件名改名为包含签出扩展名的新文件名(现实中会将文件扩展名改为.ck),其他进程只会访问那些不是.ck为扩展名的文件。

流程:

1)  程序首先得到需要访问的原文件名(比如Test.xml)

2)  使用原文件名作为基础,改名为签出文件名(比如Test.ck)

3)  因为同一时间只可能有一个进程能够修改文件名,所以当一个进程抢先与另一个进程修改了文件,那另一个进程再次使用原文件名(Test.xml)将无法访问到这个文件(因为文件名已经被修改为Test.ck)而报错(可以屏蔽这个错误),如果修改成功则表示文件已经被你签出。你可以继续使用新的文件名对文件进行修改。其他进程如果使用原文件名将无法访问这个文件。

4)  处理完数据后将文件扩展名改回原文件名(Test.xml)

 

        原理和写数据库时抢锁类似,每次访问文件前都必须首先改名(抢锁),只有抢到锁的进程才能进行后续操作。否则则等待其他进程释放锁。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页