如何在python中创建一个线程安全的单例

时间:2011-06-16 07:09:45

标签: python django singleton thread-safety

我想在我的Django应用程序中保存正在运行的线程。由于我不能在模型或会话中这样做,我想把它们放在一个单身人士中。我已经检查了一段时间,并没有真正找到一个很好的方法。

有没有人知道如何在python中创建一个线程安全的单例?

编辑:

更具体地说,我要做的是我想实现某种“随时算法”,即当用户按下按钮时,返回响应并开始新的计算(新线程)。我想要这个线程运行,直到用户再次按下按钮,然后我的应用程序将返回它设法找到的最佳解决方案。要做到这一点,我需要保存线程对象的某个地方 - 我想把它们存储在会话中,显然我做不了。

底线是 - 我想在服务器端,在不同的线程中进行FAT计算,而用户正在使用我的网站。

2 个答案:

答案 0 :(得分:3)

除非你有充分的理由 - 你应该在一个不同的进程中执行长时间运行的线程,并使用Celery来执行它们:

  

Celery是一个异步的开源软件   任务队列/作业队列基于   分布式消息传递。它是   专注于实时操作,但是   也支持调度。

     

执行单位,称为任务,是   在一个或多个上同时执行   使用多处理的工作节点,   Eventlet或gevent。任务可以执行   异步(在后台)或   同步(等到准备好了。)

djangonauts的芹菜指南:http://django-celery.readthedocs.org/en/latest/getting-started/first-steps-with-django.html

对于单身并在任务/​​线程之间共享数据,再次,除非你有充分的理由,你应该谨慎使用数据库层(又名模型)关于数据库锁定和刷新陈旧数据。

更新:关于您的使用案例,请定义Computation模型,其中包含status字段。当用户启动计算时,将创建一个实例,并且任务将开始运行。该任务将监视status字段(偶尔检查一次db)。当用户再次单击该按钮时,视图会将状态更改为user requested to stop,从而导致任务终止。

答案 1 :(得分:1)

如果您想在Web应用程序中使用异步代码,那么您采取了错误的方法。您应该使用像Celery这样的专家任务队列运行后台任务:http://celeryproject.org/

您遇到的最大问题是Web服务器架构。除非您违反推荐的Django Web服务器配置并使用工作线程MPM,否则您将无法跟踪请求之间的线程句柄,因为每个请求通常占用其自己的进程。这就是Apache正常工作的方式:http://httpd.apache.org/docs/2.0/mod/prefork.html

编辑:

根据您的编辑,我认为您可以通过创建执行此操作的自定义解决方案来了解更多信息:

  • 维护数据库中的启动/停止状态
  • 创建一个作为守护程序运行的新程序
  • 定期检查开始/停止状态并从此处开始或结束工作

除非您需要为每个用户创建新进程,否则不需要多线程处理。如果是这样,事情变得更加复杂,使用Celery将使您的生活更轻松。