• 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' + ' ')
    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' + ' ')
    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' + ' ')
    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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    艾伟:WCF中通过Dispose有效实现重用 狼人:
    艾伟:用 IIS 7、ARR 與 Velocity 建置高性能的大型网站 狼人:
    艾伟:表达式树和泛型委托 狼人:
    艾伟:jQuery性能优化指南(2) 狼人:
    艾伟:在Windows Mobile上实现自动拼写和匹配建议 狼人:
    艾伟:Web.config配置文件详解 狼人:
    艾伟:对 String 的几个错误认识 狼人:
    艾伟:ASP.NET安全问题--Forms验证的具体介绍(上篇) 狼人:
    艾伟:基于web信息管理系统的权限设计分析和总结 狼人:
    艾伟:[你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望 狼人:
  • 原文地址:https://www.cnblogs.com/ExMan/p/10144447.html
Copyright © 2020-2023  润新知