如何在Python中创建线程安全的单例
我想在 Django 应用程序中保留正在运行的线程。由于我无法在模型或会话中这样做,因此我考虑将它们保存在一个单例中。我已经检查了一段时间,但还没有真正找到一个好的方法。
有谁知道如何在 python 中创建线程安全的单例?
编辑:
更具体地说,我想做的是我想实现某种“随时算法”,即当用户按下按钮时,返回响应并开始新的计算(一个新线程)。我希望这个线程一直运行,直到用户再次按下按钮,然后我的应用程序将返回它设法找到的最佳解决方案。为此,我需要将线程对象保存在某个地方 - 我想将它们存储在会话中,但这显然是我做不到的。
底线是 - 当用户使用我的网站时,我想在服务器端以不同的线程进行 FAT 计算。
I would like to hold running threads in my Django application. Since I cannot do so in the model or in the session, I thought of holding them in a singleton. I've been checking this out for a while and haven't really found a good how-to for this.
Does anyone know how to create a thread-safe singleton in python?
EDIT:
More specifically what I wand to do is I want to implement some kind of "anytime algorithm", i.e. when a user presses a button, a response returned and a new computation begins (a new thread). I want this thread to run until the user presses the button again, and then my app will return the best solution it managed to find. to do that, i need to save somewhere the thread object - i thought of storing them in the session, what apparently i cannot do.
The bottom line is - i have a FAT computation i want to do on the server side, in different threads, while the user is using my site.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除非你有很好的理由 - 你应该在不同的进程中执行长时间运行的线程,并使用 Celery 来执行他们:
djangonauts 的 Celery 指南: http:// django-celery.readthedocs.org/en/latest/getting-started/first-steps-with-django.html
用于单例和共享数据在任务/线程之间,再次强调,除非您有充分的理由,否则您应该使用数据库层(又名模型),并对数据库锁和刷新过时数据保持谨慎。
更新:根据您的用例,定义一个带有
状态
字段的计算
模型。当用户开始计算时,就会创建一个实例,并且任务将开始运行。该任务将监视status
字段(偶尔检查一次数据库)。当用户再次单击该按钮时,视图会将状态更改为用户请求停止
,从而导致任务终止。Unless you have a very good reason - you should execute the long running threads in a different process altogether, and use Celery to execute them:
Celery guide for djangonauts: http://django-celery.readthedocs.org/en/latest/getting-started/first-steps-with-django.html
For singletons and sharing data between tasks/threads, again, unless you have a good reason, you should use the db layer (aka, models) with some caution regarding db locks and refreshing stale data.
Update: regarding your use case, define a
Computation
model, with astatus
field. When a user starts a computation, an instance is created, and a task will start to run. The task will monitor thestatus
field (check db once in a while). When a user clicks the button again, a view will change the status touser requested to stop
, causing the task to terminate.如果您希望在 Web 应用程序中使用异步代码,那么您就采取了错误的方法。您应该使用像 Celery 这样的专业任务队列来运行后台任务: http://celeryproject.org/
您遇到的最大问题是Web服务器架构。除非您违反推荐的 Django Web 服务器配置并使用工作线程 MPM,否则您将无法跟踪请求之间的线程句柄,因为每个请求通常占用自己的进程。这就是 Apache 的正常工作方式: http://httpd.apache.org/docs/ 2.0/mod/prefork.html
编辑:
根据您的编辑,我认为您可以通过创建执行此操作的自定义解决方案来了解更多信息:
这里不需要多线程,除非您需要为每个用户创建一个新进程。如果是这样,事情会变得更加复杂,而使用 Celery 会让你的生活变得更轻松。
If you want asynchronous code in a web application then you're taking the wrong approach. You should run background tasks with a specialist task queue like Celery: http://celeryproject.org/
The biggest problem you have is web server architecture. Unless you go against the recommended Django web server configuration and use a worker thread MPM, you will have no way to track your thread handles between requests as each request typically occupies its own process. This is how Apache normally works: http://httpd.apache.org/docs/2.0/mod/prefork.html
EDIT:
In light of your edit I think you might learn more by creating a custom solution that does this:
There's no need for multithreading here unless you need to create a new process for each user. If so, things get more complicated and using Celery will make your life much easier.