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

  • 相关阅读:
    archlinux .bash_history
    Ubuntu环境下挂载新硬盘
    软碟通 UltraISO U启替代品 Win32DiskImager 无设备 无盘符 无u盘 无优盘 解决方案 之diskpart
    delphi Integer overflow
    MSBuild Tools offline
    delphi synedit免费的拼写检查器dll
    git 自定义命令行
    lua编译
    gcc ar
    Windows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘
  • 原文地址:https://www.cnblogs.com/ExMan/p/10144447.html
Copyright © 2011-2022 走看看