Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread Synchronization in Django

Is there any way to block a critical area like with Java synchronized in Django?

like image 614
Fenris_uy Avatar asked Mar 28 '10 23:03

Fenris_uy


People also ask

What is thread synchronization?

Thread synchronization is the concurrent execution of two or more threads that share critical resources. Threads should be synchronized to avoid critical resource use conflicts.

What is synchronous and asynchronous Django?

Django itself is synchronous. each HTTP request will be handled completely synchronously. However you have extensions like django-channels ( https://github.com/django/channels ) , which are asynchronous and are intended for web sockets / etc.

Is multithreading possible in Django?

js has a single threaded, non-blocking I/O mode of execution, while Django being a framework of Python, has a multi-threaded mode of execution.

What is thread synchronization in Python?

The threading module provided with Python includes a simple-to-implement locking mechanism that allows you to synchronize threads. A new lock is created by calling the Lock() method, which returns the new lock. The acquire(blocking) method of the new lock object is used to force threads to run synchronously.


2 Answers

You can use locks to make sure that only one Thread will access a certain block of code at a time.

To do this, you simply create a Lock object then acquire the lock before the block of code you want to synchronize. All the threads must have access to the same Lock object for this to work. An example:

from threading import Lock, Thread

lock = Lock()

def do_something():
    lock.acquire()   # will block if another thread has lock
    try:
        # ... use lock
    finally:
        lock.release()

Thread(target=do_something).start()
Thread(target=do_something).start()

For more information , see http://effbot.org/zone/thread-synchronization.htm.

like image 98
Justin Ardini Avatar answered Sep 23 '22 19:09

Justin Ardini


My approach is to use the locking features of the database. This also works with multiple server processes.

I define a model as:

from django.db import models

class ThreadSafe(models.Model):
    key = m.CharField(max_length=80, unique=True)

And then a context manager function as:

from contextlib import contextmanager
from django.db.transaction import atomic

@contextmanager
def lock(key):
    pk = ThreadSafe.objects.get_or_create(key=key)[0].pk
    try:
        objs = ThreadSafe.objects.filter(pk=pk).select_for_update()
        with atomic():
            list(objs)
            yield None
    finally:
        pass

And then I have a thread/process safe lock by simply doing:

with lock("my_key"):
    do_scary_stuff_here()

This requires a database with support for transactions.

like image 21
Rune Kaagaard Avatar answered Sep 22 '22 19:09

Rune Kaagaard