【问题标题】:How to avoid pickling errors when sharing objects between threads?在线程之间共享对象时如何避免酸洗错误?
【发布时间】:2016-09-02 07:28:08
【问题描述】:

我有一个程序,我需要将一个全局变量存储到一个文件中。我正在使用pickle 模块执行此操作。

我还有另一个thread(Daemon=False,来自threading 模块),它有时会更改全局变量的值。该值也在全局范围(主程序)中被修改。

我每 5 秒将变量的值转储到 .pkl 文件中(使用来自 threading 模块的另一个 thread)。

但是我在执行dump方法时发现如下错误:

TypeError: can't pickle _thread.lock objects

为什么会这样?我能做些什么来解决它?

注意:我在multiprocessing 模块中找到了一些类似的答案。但我需要threading 模块的答案。

代码:

def save_state():
    while True:
        global variable

        lastSession = open('lastSession.pkl', 'wb')

        # error occurs on this line
        pickle.dump(variable, lastSession)

        lastSession.close()          
        time.sleep(5)

state_thread = threading.Thread(target = save_state)
state_thread.setDaemon(False)
state_thread.start()

# variable is changed outside this function and also in another thread(not state_thread).

【问题讨论】:

  • 您不能腌制一个锁对象,因为它与操作系统的当前状态/其他线程当前持有的信号量有关。
  • 如果你想pickle一个直接或间接引用锁的类型,你需要实现你自己的__getstate__方法。锁被释放与否都没有关系,它们不能被腌制。
  • 但是当目标函数终止时,由于只剩下一个线程,不应该释放锁吗?另外,如果你能提供一个示例代码,那真的很有帮助
  • 要讨论您的代码,我们真的需要看看它。你能告诉我们有问题的锁吗?它是您正在腌制的某个对象的属性,还是您想直接腌制它?

标签: python multithreading pickle locks


【解决方案1】:

正如其他人所提到的,您不能腌制“易失性”实体(线程、连接、同步原语等),因为它们作为持久数据没有意义。

看起来您正在尝试保存会话变量以供以后继续所述会话。对于该任务,您无法保存由于其性质而无法保存的对象。

最简单的解决方案就是忽略它们。用一些“存根”替换它们,这些“存根”会在您对它们进行任何操作时产生错误,这没有什么意义,因为丢失的变量无论如何都会产生错误(如果它掩盖了全局变量则不会,但这本身就是一个有问题的做法)。

或者,您可以在恢复会话时重新设置这些对象。但这样的逻辑必然是特定于任务的。

最后,例如IPython already has session saving/restoration logic,所以你可能根本不需要重新发明轮子。

【讨论】:

  • 您能否更具体地了解 ipython 中的会话逻辑?我也可以将这些易失性变量存储在数据库中吗?
  • 第一次:完成,第二次:你明白序列化的要点和“作为持久数据没有意义”部分了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 2019-05-06
相关资源
最近更新 更多