Синхронизация потоков в Django - PullRequest
5 голосов
/ 29 марта 2010

Есть ли способ заблокировать критическую область, как с синхронизацией Java в Django?

Ответы [ 3 ]

6 голосов
/ 29 марта 2010

Вы можете использовать блокировки, чтобы гарантировать, что только один Поток будет одновременно обращаться к определенному блоку кода.

Чтобы сделать это, вы просто создаете объект Lock, а затем получаете блокировку перед блоком кода, который хотите синхронизировать. Пример:

lock = Lock()

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

Для получения дополнительной информации см. http://effbot.org/zone/thread-synchronization.htm.

1 голос
/ 07 ноября 2018

Мой подход заключается в использовании функций блокировки базы данных. Это также работает с несколькими серверными процессами.

Я определяю модель как:

from django.db import models

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

А затем функция менеджера контекста:

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

А затем я могу заблокировать поток / процесс, просто выполнив:

with lock("my_key"):
    do_scary_stuff_here()

Для этого требуется база данных с поддержкой транзакций.

0 голосов
/ 23 июля 2014

Отличная статья Джастин, только одна вещь, использующая python 2.5, облегчает этот путь

В Python 2.5 и более поздних версиях вы также можете использовать оператор with. При использовании с блокировкой этот оператор автоматически получает блокировку перед входом в блок и снимает ее при выходе из блока:

из future import with_statement # 2.5 only

с замком: ... доступ к общему ресурсу

...