Python的多进程锁的使用

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

这个时候,我们可以使用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方法中每次写的时候先打开,写入后关闭应该也是可行的。

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

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值