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.
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
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.
- Instantiate model instance with manytomany field in Django
- Circular dependency when squashing Django migrations
- Django MySQL distinct query for getting multiple values
- Django 1.8 & Django Crispy Forms: Is there a simple, easy way of implementing a Date Picker?