在多处理中将Lock作为参数传递。为什么会这样?

时间:2018-02-24 21:37:31

标签: python-3.x multiprocessing locking

在下面的代码片段中,我看到通过打印Lock对象的地址,每个进程都获得了LOCK对象的副本。

""" Processes and Locks """

import multiprocessing as mp
import logging


logging.basicConfig(level=logging.DEBUG,
                    format='(%(processName)-10s) (%(threadName)-9s) %(message)s',)


def increase_value(iterations, value, lock):
    """Increase a shared variable"""
    print(hex(id(lock)))
    for _ in range(iterations):
        lock.acquire()
        value.value = value.value + 1
        lock.release()


def decrease_value(iterations, value, lock):
    """Decrease a shared variable"""
    print(hex(id(lock)))
    for _ in range(iterations):
        lock.acquire()
        value.value -= 1
        lock.release()


if __name__ == "__main__":
    ITERATIONS = 100000
    SHARED_VALUE = mp.Value('i', 0)
    LOCK = mp.Lock()
    print(hex(id(LOCK)))
    t1 = mp.Process(target=increase_value, 
                    args=(ITERATIONS, SHARED_VALUE, LOCK))
    t2 = mp.Process(target=decrease_value, 
                    args=(ITERATIONS, SHARED_VALUE, LOCK))

    t1.start()
    t2.start()

    t1.join()
    t2.join()

    logging.debug("SHARED VALUE %d", SHARED_VALUE.value)

为什么这样做? lock.acquire如果引用同一个锁,应该有意义。我错过了什么?

1 个答案:

答案 0 :(得分:0)

  如果

lock.acquire引用同一个锁

,那么

import os import time class VeryDumbLock: def __init__(self, filename): self.filename = filename def acquire(self): while os.path.exists(self.filename): time.sleep(0.1) with open(self.filename, 'w'): pass def release(self): os.remove(self, self.filename) 应该是有意义的

它们确实引用了相同的锁,而不是引用相同的Python对象(无论在Python进程中是什么意思)。

假装你有这个设计很差的锁:

foo = VeryDumbLock('/tmp/lock')

如果你在两个不同的进程中创建bar = VeryDumbLock('/tmp/lock')POST,那么它们实际上都是相同的锁,即使它们明显是位于内存中不同地址的不同对象。

锁定对象在后台实现的实际机制是您唯一需要关注的。