我试图找出如何在python中声明一个特定的变量被锁定,以便只有一个线程可以一次访问它以避免竞争条件。如果我有两个线程不断通过队列更新变量,但我也在main中手动更新变量,那么所有线程将该变量声明为共享资源的正确方法是什么,以便只有一个可以在一次之间访问它线程正在运行和主要?
我写了一些示例代码来说明我的意思。
import time
from random import randint
from threading import Thread
from queue import Queue
# Add the amount by random number from 1 - 3 every second
def producer(queue, amount):
while True:
time.sleep(1)
amount[0] += randint(1, 3)
queue.put(amount)
# Subtract the amount by random number from 1 - 3 every second
def consumer(queue, amount):
while True:
item = queue.get()
amount[0] -= randint(1, 3)
queue.task_done()
amount = [10]
queue = Queue()
t1 = Thread(target=producer, args=(queue, amount,))
t2 = Thread(target=consumer, args=(queue, amount,))
t1.start()
t2.start()
while True:
n = input("Type a number or q: ")
if n == 'q':
break
else:
# Here is where I am confused about how to declare the amount a
# shared resource and lock it in a way that the queues would also
# adhere to
amount[0] += int(n)
print("amount is now: {}".format(amount[0]))
t1.join()
t2.join()
在更新变量值时锁定变量很重要。所以在你的情况下你确实需要锁定机制。
如何锁定:
创建一个threading.Lock
对象,它将帮助您锁定和释放代码块。
在你的情况下:
import time
from random import randint
from threading import Thread,Lock
from queue import Queue
# Add the amount by random number from 1 - 3 every second
def producer(queue, amount,lock):
while True:
time.sleep(1)
lock.acquire()
amount[0] += randint(1, 3)
queue.put(amount)
lock.release()
# Subtract the amount by random number from 1 - 3 every second
def consumer(queue, amount,lock):
while True:
lock.acquire()
item = queue.get()
amount[0] -= randint(1, 3)
queue.task_done()
lock.release()
amount = [10]
lock = Lock()
queue = Queue()
t1 = Thread(target=producer, args=(queue, amount,lock))
t2 = Thread(target=consumer, args=(queue, amount,lock))
t1.start()
t2.start()
...