对锁定行为进行批注

若要避免在多线程程序中的并发 bug,请始终遵循相应的锁的专业并使用 SAL 注释。

因为它们是不确定的,并发 bug 公认难以重现,诊断和调试。 这些有关线程交错很困难时,并变得不可能,在模型比某些线程具有多个时代码正文。 因此,最好遵循在多线程程序中的一个锁定的专业。 例如,它们遵守锁定请顺序访问时,有助于避免死锁的多个锁时,因此,获取适当的控制锁定访问共享资源帮助之前阻止争用条件。

遗憾的是,似乎简单的锁定的规则可以是令人惊讶的是难实际上。 在今天编程语言和编译器的基本限制是它们不直接支持同时要求的说明和分析。 程序员必须依赖于非正式的代码注释表示其有关它们的视图使用锁定。

并发 SAL 注释旨在帮助您指定锁定副作用,锁定负责、数据监护,锁定命令所需的层次结构以及其他锁定行为。 通过使用隐式规则显式的,SAL 并发批注为您提供一致的方法编写代码如何使用锁规则。 并发批注还引发代码分析工具中可以找到争用条件、死锁、不匹配的同步操作和其他细微的并发错误。

通用准则

使用批注,可以按照在实现的协定 (被调用方) 和客户端 (调用方) 之间的函数定义提示,表示固定条件和进一步改进分析器的其他属性。

SAL 支持许多不同的锁定基元 (例如、临界段落、mutexes、自旋锁和其他资源对象。 许多并发批注采用锁表达式作为参数。 按照约定,锁的基础锁定对象的路径表达式表示。

某些线程所有权规则记住:

  • 自旋锁是具有广泛的线程所属权的未绑定锁。

  • Mutex 和临界段是具有广泛的线程所属权的计数的锁。

  • 信号量和事件是不具有广泛的线程所属权的计数的锁。

锁定批注

下表列出了锁的批注。

批注

描述

_Acquires_exclusive_lock_(expr)

说明一个函数并指示在 POST 状态函数由一个递增由 expr名为的锁定对象的独占锁计数。

_Acquires_lock_(expr)

说明一个函数并指示在 POST 状态函数由一个递增由 expr名为的锁定对象的锁计数。

_Acquires_nonreentrant_lock_(expr)

由 expr 名为的锁定访问。 错误报告锁是否已被保留。

_Acquires_shared_lock_(expr)

说明一个函数并指示在 POST 状态函数由一个递增由 expr名为的锁定对象的共享锁计数。

_Create_lock_level_(name)

声明符号 name 锁定级语句,以便可以用于批注 _Has_Lock_level_ 和 _Lock_level_order_。

_Has_lock_kind_(kind)

批注所有对象优化资源对象的类型信息。 有时通用类型针对不同类型的资源使用,并且该重载的类型不满足区分各种资源中的语义要求。 这是预定义的 kind 参数列表:

_Lock_kind_mutex_

mutex 的锁 kind ID。

_Lock_kind_event_

事件的锁 kind ID。

_Lock_kind_semaphore_

信号量的锁 kind ID。

_Lock_kind_spin_lock_

自旋锁的锁 kind ID。

_Lock_kind_critical_section_

临界段的锁 kind ID。

_Has_lock_level_(name)

说明锁定对象并将该 name的锁级别。

_Lock_level_order_(name1, name2)

为锁定排序。name1 和 name2之间的语句。

_Post_same_lock_(expr1, expr2)

说明一个函数并指示在 POST 状态两个锁,expr1 和 expr2,处理,则同一个锁对象。

_Releases_exclusive_lock_(expr)

说明一个函数并指示在 POST 状态函数递减一个单位由 expr名为的锁定对象的独占锁计数。

_Releases_lock_(expr)

说明一个函数并指示在 POST 状态函数递减一个单位由 expr名为的锁定对象的锁计数。

_Releases_nonreentrant_lock_(expr)

由 expr 名为的释放锁。 错误报告锁是否当前不持有。

_Releases_shared_lock_(expr)

说明一个函数并指示在 POST 状态函数递减一个单位由 expr名为的锁定对象的共享锁计数。

_Requires_lock_held_(expr)

说明一个函数并指示在之前状态由 expr 名为的对象的锁计数至少一个。

_Requires_lock_not_held_(expr)

说明一个函数并指示在之前状态由 expr 名为的对象的锁计数为零。

_Requires_no_locks_held_

说明一个函数并指示为位检查器已知的锁计数所有锁为零。

_Requires_shared_lock_held_(expr)

说明一个函数并指示在之前状态由 expr 名为的对象的共享锁计数至少一个。

_Requires_exclusive_lock_held_(expr)

说明一个函数并指示在之前状态由 expr 名为的对象的独占锁计数至少一个。

未公开固定对象的 SAL 内部

某些锁定对象没有关联的死锁的函数的实现中显示。 下表列出了在函数的批注对那些未公开锁定对象的 SAL 内部变量。

批注

描述

_Global_cancel_spin_lock_

描述取消自旋锁。

_Global_critical_region_

描述重要区域。

_Global_interlock_

描述互锁操作。

_Global_priority_region_

描述优先级区域。

共享数据访问批注

下表列出了共享数据访问的批注。

批注

描述

_Guarded_by_(expr)

说明一个变量并指示,只要该变量时,由 expr 名为的锁定对象的锁计数至少一个。

_Interlocked_

说明一个变量并将 _Guarded_by_(_Global_interlock_)等效。

_Interlocked_operand_

带批注的函数参数是目标操作的一个各种互锁的功能。 这些操作) 必须具有特定的其他属性。

_Write_guarded_by_(expr)

说明一个变量它意味着,每当修改变量,由 expr 名为的锁定对象的锁计数至少一个。

请参见

参考

对函数参数和返回值进行批注

对函数行为进行批注

批注结构和类

指定何时以及在何处应用批注

内部函数

最佳做法和示例 (SAL)

概念

了解 SAL

其他资源

使用 SAL 批注以减少 C/C++ 代码缺陷

代码分析团队博客