点击上方蓝字,关注我们
在服务端的测试体系中,数据一致性是非常核心的一部分的,比如一个服务会有多个实例,那么就需要考虑服务在多个实例下它的数据一致性的问题。在本文章中,主要探讨在并发编程的模式中,数据的安全问题。在Python的并发编程的知识体系中,进程之间是无法共享数据文件的,但是在操作系统的级别上,会共享一套文件系统的,那么既然共享,就会带来了资源的竞争,和数据的混乱,这个时候会需要对数据进行管理。此时,就会使用到Lock来处理。下面结合具体的案例来看这部分,代码如下:
#!/usr/bin/env python
#!coding:utf-8
from multiprocessing import Process
import os
import time as t
import json
import random
def data(i):
return {"name":"无涯","age":18,'item':i}
def task(i):
print('开始写数据:\n')
json.dump(data(i=i),open('log.txt','w'))
t.sleep(random.randrange(1,3))
print('读取文件:\n',json.load(open('log.txt')))
if __name__ == '__main__':
for i in range(3):
obj=Process(target=task,args=(i,))
obj.start()
在上面的代码中,我们期望的是每次IO的操作它都是独立的,也就是说在多个线程的操作模式下,每一次的IO的操作是先操作完成后再进入到下一个IO的操作,事实上并不是,执行后的结果信息如下:
发现执行的结果信息完全和预期的是不一样的,而且是三个进程先进行写,然后再进行读,这也就导致了三个进程读取出来的数据是一致的,这样其实在其他的案例上,数据安全存在很大的隐患。
在这种情况下,为了保证数据的安全以及数据的一致性,比如上面的案例中,为了保证每次的IO操作都是独立的,需要使用加锁的机制来进行解决,特别需要说明的是在 加锁之后会导致程序执行的效率降低,但是可以保证数据的安全。针对上面的程序加锁之后的代码具体如下:
#!/usr/bin/env python
#!coding:utf-8
from multiprocessing import Process,Lock
import os
import time as t
import json
import random
def data(i):
return {"name":"无涯","age":18,'item':i}
def task(lock,i):
#加锁
lock.acquire()
print('开始写数据:\n')
json.dump(data(i=i),open('log.txt','w'))
t.sleep(random.randrange(1,3))
print('读取文件:\n',json.load(open('log.txt')))
#释放锁
lock.release()
if __name__ == '__main__':
lock=Lock()
for i in range(3):
obj=Process(target=task,args=(lock,i))
obj.start()
执行后,出现的结果信息如下:
通过如上执行的结果可以得到,在加锁之后,每次IO的操作它都是独立的,这样就保证了数据的安全,虽然在性能上有点损失,但是比起数据的安全来说,损耗点性能还是可以接受的。