Python是否有一个线程安全队列可以被pickle或以其他方式序列化到磁盘?

2024-04-25 21:54:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我要的是一个线程安全队列,它可以被pickle或序列化到磁盘。python中是否有数据结构可以做到这一点。无法pickle标准python队列。在


Tags: 数据结构标准序列化队列线程pickle磁盘
2条回答

dillcloudpickle这样的模块已经知道如何序列化Queue。 他们已经为你做了copy_reg。在

>>> from Queue import Queue
>>> q = Queue()
>>> q.put('hey')
>>> import dill as pickle
>>> d = pickle.dumps(q)
>>> _q = pickle.loads(d)
>>> print _q.get()
hey
>>> 

就这么简单!只要import dill as pickle问题就解决了。在

获取dill此处:https://github.com/uqfoundation

这可以使用^{}模块来完成,但这不是世界上最优雅的事情:

import copy_reg
import threading
import pickle
from Queue import Queue as _Queue

# Make Queue a new-style class, so it can be used with copy_reg
class Queue(_Queue, object):
    pass

def pickle_queue(q):
    # Shallow copy of __dict__ (the underlying deque isn't actually copied, so this is fast)
    q_dct = q.__dict__.copy()
    # Remove all non-picklable synchronization primitives
    del q_dct['mutex']
    del q_dct['not_empty']
    del q_dct['not_full']
    del q_dct['all_tasks_done']
    return Queue, (), q_dct

def unpickle_queue(state):
    # Recreate our queue.
    q = state[0]()
    q.mutex = threading.Lock()
    q.not_empty = threading.Condition(q.mutex)
    q.not_full = threading.Condition(q.mutex)
    q.all_tasks_done = threading.Condition(q.mutex)
    q.__dict__ = state[2]
    return q

copy_reg.pickle(Queue, pickle_queue, unpickle_queue)

q = Queue()
q.put("hey")
d = pickle.dumps(q)

new_q = pickle.loads(d)
print new_q.get()
# Outputs 'hey'

copy_reg允许您注册helper函数或pickle和unpickle任意对象。因此,我们注册了Queue类的一个新版本,并使用helper函数在pickle之前删除所有不可拾取的Lock/Condition实例变量,并在取消拾取后将其添加回。在

相关问题 更多 >