社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在线程安全对象上使用包装器的python线程

Fleetscut • 5 年前 • 1278 次点击  

我开始学习在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调用,但是错误开始在所有运行中发生。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/40893
 
1278 次点击  
文章 [ 1 ]  |  最新文章 5 年前
Carcigenicate
Reply   •   1 楼
Carcigenicate    6 年前

不要使用集合来传递参数。在许多python版本中,集合是无序的。你不能保证在迭代时它们的顺序和字面的顺序是一样的。似乎是 1 q 在迭代时交换位置。我可以在我的python版本中半复制它:

q = queueWrapper()
lock = threading.Lock()

print(*{1, q, lock}) 

1 <unlocked _thread.lock object at 0xe7560830> <__main__.queueWrapper object at 0xe7552f50>

注意队列和锁是如何交换位置的。

改用列表或元组。两者都能妥善维持秩序:

producer1 = threading.Thread(target = producer, name = 'Add 1', args = (1, q, lock))