Django中的线程同步

5 投票
4 回答
6214 浏览
提问于 2025-04-15 20:57

有没有什么方法可以在Django中像Java的synchronized那样阻止关键区域的访问?

4 个回答

0

很棒的文章,Justin!不过有一点,使用Python 2.5会让这个过程简单很多。

在Python 2.5及之后的版本中,你可以使用“with”语句。当这个语句和锁一起使用时,它会在进入代码块之前自动获取锁,并在离开代码块时释放锁:

from future import with_statement # 仅适用于2.5

with lock: ... 访问共享资源

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

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

6

你可以使用锁来确保只有一个线程在某个代码块中运行。

要做到这一点,你只需要创建一个 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

撰写回答