我开始学习在python中使用线程,我想看看如果将线程安全的对象包装在类或其他对象中,它是否仍然是安全的。
我为队列编写了一个简单的包装:
队列包装器.py
import queue
import time
class queueWrapper(object):
def __init__(self):
self.queue = queue.Queue()
def addItem(self, id, item):
try:
self.queue.put(f'Item {id}:{item}')
except:
print('Add Error')
def getItem(self):
try:
item = self.queue.get()
except:
print('Get Error')
else:
self.queue.task_done()
return item
然后我写了这个来使用它:
Me.Py
import threading
import time
from queueWrapper import *
def producer(id, q, lock):
for i in range(10):
# time.sleep(1)
with lock:
q.addItem(id, i)
print(f'Worker {id}: Adding {i}')
def consumer(id, q, lock):
for i in range(20):
# time.sleep(0.1)
with lock:
item = q.getItem()
if item:
print(f'Get: Got {item}')
lock = threading.Lock()
q = queueWrapper()
producer1 = threading.Thread(target = producer, name = 'Add 1', args = {1, q, lock})
producer2 = threading.Thread(target = producer, name = 'Add 2', args = {2, q, lock})
consumer1 = threading.Thread(target = consumer, name = 'Get', args ={1, q, lock})
producer1.start()
producer2.start()
consumer1.start()
producer1.join()
producer2.join()
consumer1.join()
在我添加锁之前,我得到了下面的错误。在我添加锁之后,在某些运行中它将运行到完成,但在其他运行中它仍然会给出错误
Exception in thread Add 2:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "/home/fleetscut/programming/python/threads/queue_wrapper/main.py", line 9, in producer
q.addItem(id, i)
AttributeError: 'int' object has no attribute 'addItem'
我认为这可能是由于尝试过快地添加/获取项,所以我在每个线程方法中添加了time.sleep调用,但是错误开始在所有运行中发生。