用法¶
要在项目中使用的 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
使用公平锁时,锁本身会稍微昂贵一些(在大多数情况下这无关紧要),但它将确保所有阻塞等待锁的线程将按照它们阻塞的顺序获取锁。
例外情况是在同时指定external和fair锁时。在这种情况下,给定进程内部的顺序将是公平的,但进程之间的顺序将由底层操作系统的行为决定。
常用的前缀/命名空间 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