用法

要在项目中使用的 oslo.concurrency,请导入相关的模块。例如

from oslo_concurrency import lockutils
from oslo_concurrency import processutils

参见

锁定函数(进程内)

为了确保一个函数(不是线程安全的)以线程安全的方式使用(通常应该重构这种类型的函数以避免这个问题,但如果不能,则以下方法可以提供帮助)

@lockutils.synchronized('not_thread_safe')
def not_thread_safe():
    pass

一旦装饰后,后续调用此函数的用户将能够调用此方法,并且保证两个线程将不会同时进入此函数。请确保使用的锁的名称经过仔细选择(通常通过命名空间到您的应用程序,以便其他应用程序不会选择相同的名称)。

锁定函数(进程内和跨进程)

为了确保一个函数(不是线程安全的或者多进程安全的)以安全的方式使用(通常应该重构这种类型的函数以避免这个问题,但如果不能,则以下方法可以提供帮助)

@lockutils.synchronized('not_thread_process_safe', external=True)
def not_thread_process_safe():
    pass

一旦装饰后,后续调用此函数的用户将能够调用此方法,并且保证两个线程(或任何两个进程)将不会同时进入此函数。请确保使用的锁的名称经过仔细选择(通常通过命名空间到您的应用程序,以便其他应用程序不会选择相同的名称)。

启用公平锁

默认情况下,没有要求锁是公平的。也就是说,一个线程可能会阻塞等待锁,然后另一个线程阻塞等待锁,当当前所有者释放锁时,第二个等待者可能会先获取锁,而不是第一个。在极端情况下,可能会有一整串其他线程在第一个等待者获取锁之前获取锁,从而导致不可预测的延迟。

对于存在这种情况的情况,可以指定使用公平锁

@lockutils.synchronized('not_thread_process_safe', fair=True)
def not_thread_process_safe():
    pass

使用公平锁时,锁本身会稍微昂贵一些(在大多数情况下这无关紧要),但它将确保所有阻塞等待锁的线程将按照它们阻塞的顺序获取锁。

例外情况是在同时指定externalfair锁时。在这种情况下,给定进程内部的顺序将是公平的,但进程之间的顺序将由底层操作系统的行为决定。

常用的前缀/命名空间 synchronized 装饰器

由于强烈建议对 synchronized 的使用进行前缀(或命名空间),因此有一些辅助工具可以使实现起来更容易。

一个例子是

myapp_synchronized = lockutils.synchronized_with_prefix("myapp")

然后,进一步使用lockutils.synchronized将改为使用上面创建的装饰器,而不是直接使用lockutils.synchronized

命令行包装器

oslo.concurrency包含一个命令行工具,用于在需要设置环境变量OSLO_LOCK_PATH的测试作业中使用。要使用它,请在要运行的命令前加上lockutils-wrapper。例如

$ lockutils-wrapper env | grep OSLO_LOCK_PATH
OSLO_LOCK_PATH=/tmp/tmpbFHK45