如何在线程

时间:2018-03-02 06:14:37

标签: python multithreading concurrency queue locking

我试图找出如何在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()

1 个答案:

答案 0 :(得分: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()
 ...