【问题标题】:Are Django signals thread safe?Django 信号线程安全吗?
【发布时间】:2014-01-03 15:56:16
【问题描述】:

如果我在单线程上下文中断开然后连接一些信号,会影响其他线程使用的信号池吗?

更新
我会尽量具体一点。

我正在为少数发送者使用 post_save 和 pre_delete 信号,触发特定模型(一个特定模型)的全文引擎重新索引,这是全文引擎的主要内容来源。

重新索引是通过 Celery 任务完成的,信号处理程序只需将重新索引任务分派给代理(在我的情况下为 Redis)。

一些 post_save 信号不应触发重新索引(即不应调度 Celery 任务,pre_delete 应始终触发重新索引),因为某些模型更改与全文引擎内容无关(即状态更改、时间戳更改等)。我不太能够在每种情况下验证处理程序 kwargs 中的 update_fields,因为据我观察,管理站点保存操作没有指定这些。

我正在使用自定义上下文管理器,它将重新索引处理程序与特定发送者的 post_save 信号断开连接,将控制权返回给调用一段代码,然后执行模型上的保存操作,当控制权传递回上下文管理器时,所有重新索引处理程序正在重新连接到特定发件人的 post_save 信号。

我想确保在单线程上下文中执行的上下文管理器中的这个断开/连接例程不会影响其他线程(也就是说 - 在单线程上下文中断开的所有信号仍将在其他线程中连接)。

谢谢! 无拘无束的

【问题讨论】:

标签: django signals


【解决方案1】:

如果您的代码如下所示:

@contextmanager
def disable_signal():
   try:
      post_save.disconnect(your_signal)
      yield None
   finally: 
      post_save.connect(your_signal)

这不是线程安全的,因为我们正在更改全局变量。 https://docs.python.org/3/library/contextlib.html#reentrant-context-managers

还要注意,可重入与线程安全不是一回事。例如,redirect_stdout() 绝对不是线程安全的,因为它通过将 sys.stdout 绑定到不同的流来对系统状态进行全局修改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多