如何在线程中使用队列时为main中的特定变量创建锁

问题描述 投票:1回答:1

我试图找出如何在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()
python multithreading concurrency queue locking
1个回答
0
投票

在更新变量值时锁定变量很重要。所以在你的情况下你确实需要锁定机制。

如何锁定:

创建一个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()
 ...
© www.soinside.com 2019 - 2024. All rights reserved.