很多时候,我们需要在多个进程中同时写一个文件,如果不加锁机制,就会导致写文件错乱

这个时候,我们可以使用multiprocessing.Lock()

我一开始是这样使用的:

import multiprocessing
lock = multiprocessing.Lock()
class MatchProcess(multiprocessing.Process):
def __init__(self, threadId, mfile, lock):
multiprocessing.Process.__init__(self)
self.threadId = threadId
self.mfile = mfile
self.lock = lock
def run(self):
while True:
self.lock.acquire()
try:
self.mfile.write('111111111111111111' + '\n')
finally:
self.lock.release()

if __name__ == '__main__':
mf = open('test.lst', 'w')
for i in range(15):
p = MatchProcess(i, mf, lock)
p.start()

发现这种方式,锁并没有起作用, 文件内容依然出现了错乱(注意,我这里写的1111是示例,我的代码实际写的其他内容)

所以这种方式,虽然lock通过参数传到了每个进程中,但是我们知道进程之间是不共享内存的,所以我理解应该是每个进程获得的锁其实是不同的, 所以无法对写文件起到加锁的效果

进程池是否可行呢,于是做了如下尝试

def run(line):
lock.acquire()
try:
mfile.write('111111111111111111' + '\n')
finally:
lock.release()
sf = open('test.lst', 'r')
data_lst = list()
for line in sf:
line = line.strip()
data_lst.append(line)
pool = Pool(15)
pool.map_async(run, data_lst) #map_async方法会将data_lst这个可迭代的对象里面的每个元素依次传入run方法来执行
pool.close()
pool.join()
print 'over'

但是注意:

pool.close()
pool.join()

这两行代码必不可少,否则,主进程执行完毕后会退出,导致整个进程结束
所以在整个进程全部执行完毕后,才会打印出over

但是这种方式,发现,锁仍然不起作用

最后采用了如下方式:

def run(line):
mfile = open('test2.lst', 'a')
lock.acquire()
try:
mfile.write('111111111111111111' + '\n')
finally:
lock.release()

sf = open('test.lst', 'r')
data_lst = list()
for line in sf:
line = line.strip()
data_lst.append(line)

pList = []
for line in line_lst:
p = multiprocessing.Process(target=run, args=(line, lock))
p.start()
pList.append(p)

for p in pList:
p.join()

是亲测发现,这种方式,锁的确起作用了,在每次写入数据量很大的情况下,速度很慢
但是一个比较恶心的问题是,我一开始试图将文件打开后通过Process对象的args参数传入到run方法中,但是发现数据无法写入到文件中,见鬼,这个问题我还没搞明白

无耐,只能采取上面的笨方法,在每次写入的时候打开然后写入,这肯定不是明智的做法,如果有更好的办法,请留言我

也就是说,文件打开后传入,是无效的,那么可以将文件名传入,然后在run方法中每次写的时候先打开,写入后关闭应该也是可行的。

但是为什么我文章采用的第一种方式,也是文件打开后传入,却是可行的

---------------------
作者:田野上的希望
来源:CSDN
原文:https://blog.csdn.net/u011734144/article/details/78743240
版权声明:本文为博主原创文章,转载请附上博文链接!

最新文章

  1. p命名空间的使用(不推荐用)
  2. QueryRunner类
  3. 数据库SQL 多态
  4. phalcon: 上下文转义
  5. easyui datagrid 学习
  6. LeetCode46,47 Permutations, Permutations II
  7. 区分int a() 和 int a
  8. MySQL Cluster2个数据节点压力测试--mysqlslap工具压400W写
  9. Emacs学习阶段小结-Emacs常用快捷键总结
  10. HDOJ2005-第几天?
  11. Dynamics CRM2016 Web API之Retrieve Multiple
  12. iOS中NSBundle的介绍
  13. iOS 开发笔记 - 导航到地图
  14. POI 海量数据/大数据文件生成SXSSFWorkbook使用简介
  15. [原]Docker-issue(1) image name 显示为 <none>
  16. 【BZOJ3036】绿豆蛙的归宿 概率DP
  17. Jquery如何禁止鼠标右键菜单
  18. golang web框架 beego
  19. Python的generator生成器
  20. Swift 使用 #warning

热门文章

  1. RabbitMQ核心组件及应用场景
  2. ssh的安装和使用
  3. nginx源码学习资源(不断更新)转
  4. csu1527: Bounty Hunter
  5. Linux常用C函数-接口处理篇(网络通信函数)
  6. SolidEdge如何为零件指定不同的颜色 给零件着色 给装配体着色
  7. CMS - tabBar
  8. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂
  9. ActiveMQ(五) 转
  10. Struts2实现空表单信息的提示