在Python的多处理中使用锁时出错

2024-05-12 14:49:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python初学者,在多处理过程中使用锁时遇到了一些问题。 我得到了退出代码0和正确答案,但仍然有一些错误消息,我真的不完全理解。这是我写的代码-

import time
import multiprocessing


def deposit(balance):
     for i in range(100):
         time.sleep(0.01)
         lck.acquire()
         balance.value += 1
         lck.release()

def withdraw(balance):
    for i in range(100):
        time.sleep(0.01)
        lck.acquire()
        balance.value -= 1
        lck.release()


if __name__ == '__main__':
    balance = multiprocessing.Value('i', 200)
    lck = multiprocessing.Lock()
    d = multiprocessing.Process(target=deposit, args=(balance,))
    w = multiprocessing.Process(target=withdraw, args=(balance,))
    d.start()
    w.start()
    d.join()
    w.join()
    print(balance.value)

这是我得到的错误

 `Process Process-1:
  Traceback (most recent call last):
  File "C:\Users\rahul\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 
  315, in _bootstrap
  self.run()
  File "C:\Users\rahul\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 
  108, in run
  self._target(*self._args, **self._kwargs)
  File "C:\Users\rahul\PycharmProjects\pythonProject\LearningPython.py", line 10, in deposit
  lck.acquire()
  NameError: name 'lck' is not defined
  Process Process-2:
  Traceback (most recent call last):
  File "C:\Users\rahul\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 
  315, in _bootstrap
  self.run()
  File "C:\Users\rahul\AppData\Local\Programs\Python\Python39\lib\multiprocessing\process.py", line 
  108, in run
  self._target(*self._args, **self._kwargs)
  File "C:\Users\rahul\PycharmProjects\pythonProject\LearningPython.py", line 17, in withdraw
  lck.acquire()
  NameError: name 'lck' is not defined
  200

进程已完成,退出代码为0


Tags: inpyselftargetlineargsmultiprocessingprocess
2条回答

这里的问题是lck超出了子进程的范围。全局变量不会在进程之间共享。尝试将锁传递到进程中

或者按照kahn回答中的建议使用线程。他们更加友好,在这种情况下仍然可以正常工作

import time
import multiprocessing


def deposit(balance,lck):
     for i in range(100):
         time.sleep(0.01)
         lck.acquire()
         balance.value += 1
         lck.release()

def withdraw(balance,lck):
    for i in range(100):
        time.sleep(0.01)
        lck.acquire()
        balance.value -= 1
        lck.release()


if __name__ == '__main__':
    balance = multiprocessing.Value('i', 200)
    lck = multiprocessing.Lock()
    d = multiprocessing.Process(target=deposit, args=(balance,lck))
    w = multiprocessing.Process(target=withdraw, args=(balance,lck))
    d.start()
    w.start()
    d.join()
    w.join()
    print(balance.value)

因为depositwithdraw在其他进程中运行。在他们看来,该进程不是__main__,因此if语句没有执行,并且lck没有定义

试运行

import os
import multiprocessing


def deposit(balance):
    print(os.getpid(),__name__)


def withdraw(balance):
    print(os.getpid(),__name__)


if __name__ == '__main__':
    print(os.getpid(), __name__)
    balance = multiprocessing.Value('i', 200)
    lck = multiprocessing.Lock()
    d = multiprocessing.Process(target=deposit, args=(balance,))
    w = multiprocessing.Process(target=withdraw, args=(balance,))
    d.start()
    w.start()
    d.join()
    w.join()

在我的例子中,它显示了

19604 __main__
33320 __mp_main__
45584 __mp_main__

如果你把lck = multiprocessing.Lock()放在if之外,你的代码就可以运行。但我肯定这不是你想要的

在本例中,您应该使用threading而不是multiprocess,并了解多线程和多进程之间的区别

相关问题 更多 >