跳到主要内容
版本:master

try_lock 语句

语法


注释:

  1. 锁定列表的定义:
  • 待锁定项2 (, 待锁定项)*
  1. 待锁定项的定义:

描述

try_lock 语句用于锁定若干指定的 可锁定目标,并阻塞直到所有的锁定成功。

可锁定目标 包括以下类型的表达式:

  • handle: 如果给定的 handle 是一个 object,则如同锁定该对象的域;否则锁定该 handle 本身。
  • string: (不常用)根据名称查找 pseudo handle 并锁定它。
  • array: 数组应当(仅)包含若干 可锁定目标 元素,锁定这些元素。

如果遇到不可锁定的类型,抛出异常。

如果在尝试锁定某些 可锁定目标 时,因为锁优先级冲突或其他检查违例,抛出异常。GS 保证不会因为锁定顺序不一致而死锁。

handle 的锁定方法各不相同,也并非所有的 handle 都能被 try_lock 语句锁定,取决于具体的 handle 类型:

常见 handle 类型锁定级别是否支持 锁定
pseudoATOM_LOCK(255)
不能使用 try_lock 锁定
programATOM_LOCK(255)
不能使用 try_lock 锁定
domainDOMAIN_LOCK(1)
objectDOMAIN_LOCK(1)
try_lock 语句锁定 object 等效于锁定对象的域
sync_objectATOM_LOCK(255)
不能使用 try_lock 锁定
queueATOM_LOCK(255)
不能使用 try_lock 锁定
coCO_LOCK(254)
无法锁定 当前 协程
socketATOM_LOCK(255)
不能使用 try_lock 锁定
deviceATOM_LOCK(255)
不能使用 try_lock 锁定
urlATOM_LOCK(255)
不能使用 try_lock 锁定
timerATOM_LOCK(255)
不能使用 try_lock 锁定
share_valueSHARE_LOCK(100)
ref_valueSHARE_LOCK(100)
archiveATOM_LOCK(255)
不能使用 try_lock 锁定
domain_valueSHARE_LOCK(100)
weak_tableATOM_LOCK(255)
不能使用 try_lock 锁定

注:

  1. 不支持读锁定的 handle,即使在锁定列表中指定了 read: 前缀,也会被当作写锁定处理。
  2. 尝试锁定 domain 时,会先释放当前域

try_lock 检查规则

try_lock 会对待锁定的 handle 进行如下检查:

  • 类型可以被锁定(是 handle 类型,并且其锁定等级小于 ATOM_LOCK(255),见上表)
  • 要锁定的不是 当前 协程
  • 嵌套的 try_lock 语句不能超过 8
  • 如果当前域有优先级,则 try_lock 只能锁定优先级相同,且大于当前域优先级的 domain,不能锁定其他类型
  • 嵌套的锁定操作中,要锁定的 handle 优先级要大于上一层锁定的 handle 的优先级最大值

读锁定

允许在锁定 handle 时,指定以 锁定的方式锁定 share_valueref_valuedomain_value:

try_lock(read: sv1)
{
// ...
}

允许多个协程同时以 锁定的方式锁定同一个 share_valueref_valuedomain_value。读锁定和写锁定互斥。

对于不支持读锁定的 handle,即使在锁定列表中指定了 read: 前缀,也会被当作写锁定处理。

示例

#pragma parallel
readonly share_value sv := share_value.allocate("sv", {});
// 读可以并行
mixed read_sv(mixed k)
{
mixed v;
try_lock(read: sv) {
v = sv.get(k);
}
return v;
}

void write_sv(mixed k, mixed v)
{
try_lock(sv) {
sv.set(k, v);
}
}