Django 中的线程同步

发布于 2024-08-27 02:12:35 字数 36 浏览 6 评论 0原文

有没有办法像Django中的Java同步一样阻塞关键区域?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酒儿 2024-09-03 02:12:35

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

为此,您只需创建一个 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

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.

赠意 2024-09-03 02:12:35

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

我将模型定义为:

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

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

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.

流星番茄 2024-09-03 02:12:35

很棒的文章 Justin,只有一件事是使用 python 2.5 使这种方式变得更容易

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

from future import with_statement # 2.5 仅

使用锁:
...访问共享资源

Great article Justin, just one thing using python 2.5 makes this way easier

In Python 2.5 and later, you can also use the with statement. When used with a lock, this statement automatically acquires the lock before entering the block, and releases it when leaving the block:

from future import with_statement # 2.5 only

with lock:
... access shared resource

梦途 2024-09-03 02:12:35

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

If you are using PostgreSQL, you could use advisory locks. Any process or thread could acquire or release this lock, assuming they are all connecting to the same PostgreSQL database. django-pglocks takes this approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文