Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a thread-safe singleton in python

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.

like image 234
Nachshon Schwartz Avatar asked Jun 16 '11 07:06

Nachshon Schwartz


People also ask

How do I make singleton thread safe?

Thread Safe Singleton in Java In general, we follow the below steps to create a singleton class: Create the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.

Is a singleton thread safe?

Singleton pattern in java that is Thread safe, Reflection proof, can be used with serialization. private static volatile SingletonClass sSoleInstance; //private constructor.

How do you make a class thread safe in Python?

You can make a thread-safe list by using a mutual exclusion (mutex) lock via the threading. Lock class.


2 Answers

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.

like image 148
Udi Avatar answered Nov 02 '22 23:11

Udi


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.

like image 30
jond3k Avatar answered Nov 03 '22 00:11

jond3k