5

有什么方法可以阻止像在 Django 中同步的 Java 这样的关键区域?

4

4 回答 4

7

您可以使用锁来确保一次只有一个线程可以访问某个代码块。

为此,您只需创建一个Lock对象,然后在要同步的代码块之前获取锁。所有线程必须有权访问同一个Lock对象才能使其工作。一个例子:

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()

有关详细信息,请参阅http://effbot.org/zone/thread-synchronization.htm

于 2010-03-28T23:15:25.103 回答
4

我的方法是使用数据库的锁定功能。这也适用于多个服务器进程。

我将模型定义为:

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()

这需要一个支持事务的数据库。

于 2018-11-07T16:08:21.227 回答
0

伟大的文章贾斯汀,只有一件事使用 python 2.5 使这种方式更容易

在 Python 2.5 及更高版本中,您还可以使用 with 语句。当与锁一起使用时,此语句在进入块之前自动获取锁,并在离开块时释放它:

from future import with_statement # 2.5 only

带锁:...访问共享资源

于 2014-07-23T01:29:57.363 回答
0

如果您使用的是 PostgreSQL,则可以使用咨询锁。任何进程或线程都可以获取或释放这个锁,假设它们都连接到同一个 PostgreSQL 数据库。 django-pglocks采取这种方法。

于 2021-11-02T11:10:52.910 回答