如何在Python中创建线程安全的单例

发布于 2024-11-16 02:03:48 字数 341 浏览 4 评论 0原文

我想在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天涯沦落人 2024-11-23 02:03:49

除非你有很好的理由 - 你应该在不同的进程中执行长时间运行的线程,并使用 Celery 来执行他们:

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

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

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 is an open source asynchronous
task queue/job queue based on
distributed message passing. It is
focused on real-time operation, but
supports scheduling as well.

The execution units, called tasks, are
executed concurrently on one or more
worker nodes using multiprocessing,
Eventlet or gevent. Tasks can execute
asynchronously (in the background) or
synchronously (wait until ready).

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 a status field. When a user starts a computation, an instance is created, and a task will start to run. The task will monitor the status field (check db once in a while). When a user clicks the button again, a view will change the status to user requested to stop, causing the task to terminate.

眼泪也成诗 2024-11-23 02:03:49

如果您希望在 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:

  • Maintains start/stop state in the database
  • Create a new program that runs as a daemon
  • Periodically check the start/stop state and begin or end work from here

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文