说明

注意:此手册页的文本基于GNU C库手册的" POSIX安全概念"部分中的内容。可以在该手册中找到有关此处描述主题的更多详细信息。

各种功能手册页都包括"属性"部分,该部分描述了在各种情况下调用函数的安全性。本节使用以下安全标记注释功能:

MT-Safe
在存在其他线程的情况下,可以安全地调用MT安全或线程安全功能。 MT-Safe中的MT代表多线程。
成为MT-Safe并不意味着功能是原子性的,也不意味着它使用POSIX公开给用户的任何内存同步机制。甚至有可能依次调用MT-Safe功能不会产生MT-Safe组合。例如,让一个线程一个接一个地调用两个MT-Safe功能并不能保证等同于原子执行两个功能组合的行为,因为其他线程中的并发调用可能会以破坏性的方式进行干扰。
可跨库接口内联函数的整个程序优化可能会暴露不安全的重新排序,因此不建议跨GNU C库接口执行内联。在整个程序优化中,不能保证已记录的MT安全状态。但是,用户可见的标头中定义的函数被设计为可以安全地进行内联。
MT-Unsafe
MT-Unsafe函数在多线程程序中调用是不安全的。

安全说明中出现的其他关键字将在后续章节中定义。

Conditionally safe features

对于某些使函数在某些情况下不安全调用的功能,除了避免完全调用函数外,还有其他避免安全问题的已知方法。后面的关键字指的是这样的功能,它们的每个定义都指示如何限制整个程序,以消除关键字所指示的安全问题。只有通过应用记录的约束,观察到并解决了使函数不安全的所有原因,才能在上下文中安全调用函数。

init
首次调用时,带有init标记为MT-Unsafe功能的函数将执行MT-Unsafe初始化。
在单线程模式下至少调用一次此函数可以消除导致该函数被视为MT不安全的特定原因。如果没有其他原因,则可以在启动其他线程之后安全地调用该函数。
race
用种族注释的功能作为MT安全问题在对象上运行,其方式可能会导致数据竞争或类似形式的破坏性干扰,无法并行执行。在某些情况下,对象由用户传递给功能。在其他情况下,函数会使用它们将值返回给用户;在其他情况下,它们甚至不会暴露给用户。
const
用const标记为MT安全性的函数会非原子地修改内部对象,而内部对象最好视为常量,因为GNU C库的很大一部分无需同步即可访问它们。与种族不同,种族使内部对象的读取者和写入者都被视为MT-不安全,此标记仅适用于写入者。编写者保持MT-Unsafeto调用,但是他们修改的对象的强制性常量使读者可以被视为MT-Safe(只要不存在其他导致他们不安全的原因),因为在这种情况下缺少同步不会成为问题对象实际上是恒定的。
const标记后面的标识符将自己作为安全说明出现在阅读器中。希望解决此安全问题的程序可以调用写程序,可以使用与标识符关联的非递归读写锁,并保护对所有以const标记的函数的调用,以及随后带有写锁的标识符,以及所有对带有标识符的功能的调用均带有读锁。
sig
以sig标记为MT安全问题的功能可能会出于内部目的临时安装信号处理程序,这可能会干扰以冒号标识的信号的其他用途。
通过确保在通话期间不会发生信号的其他使用,可以解决此安全问题。在调用使用相同临时信号的所有函数时,持有非递归互斥体;建议在调用之前阻塞该信号,然后再重置其处理程序。
term
标记为MT安全问题的功能可能会以建议的方式更改终端设置,即:调用tcgetattr(3),修改某些标志,然后调用tcsetattr(3),这将创建一个窗口,其他用户在此进行更改线程丢失。因此,标有term的功能是MT不安全的。
因此,建议使用终端的应用程序避免与它进行并发和可重入的交互,方法是不在信号处理程序中使用它或阻止可能使用它的信号,并在调用这些函数并与终端进行交互时保持锁定。此锁还应与带有race:tcattr(fd)标记的功能一起互斥,其中fd是控制终端的文件描述符。为了简单起见,调用者可以使用一个互斥锁,或者即使每个终端都被不同的文件描述符引用,每个终端也可以使用一个互斥锁。

Other safety remarks

附加的关键字可以附加到函数中,以指示不会使函数调用不安全的功能,但是在某些程序类别中可能需要考虑这些功能:

locale
用语言环境注释的功能是从语言环境对象读取的MT安全问题,而没有任何形式的同步。用语言环境注释的功能与语言环境更改并发调用时,其功能可能与在其执行过程中未处于活动状态的任何语言环境相对应,但它们的作用不可预测。
但是,我们不会将这些功能标记为MT-不安全,因为修改语言环境对象的功能会标记为const:locale并被视为不安全。由于不安全,当运行多个线程或启用了异步信号时,将不调用后者,因此在这些情况下可以认为语言环境有效地保持不变,这使得前者很安全。
env
带有env标记为MT安全性问题的函数使用getenv(3)或类似名称访问环境,而没有任何保护措施可确保在进行并发修改时确保安全性。
但是,我们不会将这些功能标记为MT-不安全,因为修改环境的功能都标有const:env并被视为不安全。由于不安全,当运行多个线程或启用了异步信号时,不应调用后者,因此在这些情况下可以认为环境实际上是恒定的,这使得前者很安全。
hostid
用hostid标记为MT安全性问题的功能将从保存机器"主机ID"的系统范围数据结构中读取。这些数据结构通常不能自动进行修改。由于预期"主机ID"通常不会更改,因此从其中读取的函数(gethostid(3))被认为是安全的,而对其进行修改的函数(sethostid(3))被标记为const:hostid ,表示如果要调用它,可能需要特别注意。在这种特定情况下,特别注意相当于系统范围(而不仅仅是进程内)的协调。
soirntr
用soirntr标记为MT安全性问题的函数无需任何保护即可访问GNU C库_soirntr内部数据结构,以确保在进行并发修改时的安全性。
但是,我们不会将这些功能标记为MT-不安全,因为修改此数据结构的功能均标记为const:soirntr并被视为不安全。由于不安全,当多个线程正在运行或启用了异步信号时,将不调用后者,因此在这些情况下可以认为数据结构有效地保持不变,这使得前者很安全。
cwd
标有cwd作为MT安全问题的函数可能会在执行过程中临时更改当前工作目录,这可能导致相对路径名在其他线程中或在异步信号或取消处理程序中以意外方式解析。
这还不足以将如此标记的功能标记为MT-不安全,但是如果此行为是可选的(例如,带有FTW_CHDIR的nftw(3)),则避免使用该选项可能是使用完整路径名或文件描述符的不错选择。 -相对(例如,openat(2))系统调用。
:identifier
有时可能在注释后面加上标识符,这些标识符旨在对多个函数进行分组,例如,以不安全的方式(例如race和const)访问数据结构,或提供更具体的信息,例如在标有的函数中标记信号。信号可以设想,将来也可以将其应用于锁定和破坏。
在大多数情况下,标识符将命名一组函数,但也可以使用诸如:buf(arg)之类的符号来命名全局对象或函数自变量,或与它们关联的可识别属性或逻辑组件。与参数arg或:tcattr(fd)关联的缓冲区,以表示文件描述符fd的终端属性。
标识符的最常见用途是提供功能和自变量的逻辑组,这些组必须由相同的同步原语保护,以确保在给定上下文中的安全操作。
/condition
一些安全注释可能是有条件的,因为它们仅在涉及参数,全局变量甚至底层内核的布尔表达式评估为true时才适用。例如,/!ps和/ one_per_line表示前面的标记仅在参数ps为NULL或全局变量one_per_line为非零时适用。
当所有使功能不安全的标记都带有此类条件装饰,而没有任何指定的条件成立时,则该功能可以视为安全的。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

另外参见

pthreads(7)

名称

属性-POSIX安全概念

属性 - Linux手册页

Linux程序员手册 第7部分
更新日期: 2015-03-02

日期:2019-08-20 18:01:52 来源:oir作者:oir