首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM C 库中的线程安全性(2)

ARM C 库中的线程安全性(2)

非线程安全的函数
Table 2.2 显示了非线程安全的 C 库函数。
Table 2.2. 非线程安全的函数
函数说明setlocale()语言环境设置是所有线程的全局设置,并且未使用锁对其进行保护。如果两个线程调用setlocale(),则可能会发生数据损坏。 另外,很多其他函数读取当前语言环境设置,例如,strtod() 和 sprintf()。因此,如果一个线程调用 setlocale(),另一个线程同时调用此函数,则可能会产生意外结果。
ARM 建议您选择所需的语言环境,然后调用一次 setlocale() 以对其进行初始化。 应在程序中创建任何其他线程之前执行此操作,以使任意数量的线程可以同时读取语言环境设置,而不会相互干扰。
请注意,localeconv() 不是线程安全的。应改用指向用户提供的缓冲区的指针调用 ARM 函数 _get_lconv()。
asctime(), localtime(),strtok()这些函数不是线程安全的。 每个函数都包含一个静态缓冲区,其他线程可能会在调用函数以及随后使用其返回值之间覆盖该缓冲区。
ARM 提供了可重入版本 _asctime_r()、_localtime_r() 和 _strtok_r()。 ARM 建议您改用这些函数以确保安全。
Note这些可重入版本使用一些附加参数。_asctime_r() 使用的附加参数是指向输出字符串要写入的缓冲区的指针。_localtime_r() 使用的附加参数是指向结果要写入的 struct tm 的指针。_strtok_r() 使用的附加参数也是一个指针,指向的是指向下一个标记的 char 指针。

gamma()[1], lgamma()这些扩展 mathlib 函数使用全局变量 _signgam,因此不是线程安全的。mbrlen(), mbsrtowcs(),mbrtowc(),wcrtomb(),wcsrtombs()stdlib.h 中定义的 C89 多字节转换函数(如 mblen() 和 mbtowc())不是线程安全的,因为它们包含在所有线程之间共享而没有锁定的内部静态状态。
但是,wchar.h 中定义的扩展可重启版本(例如,mbrtowc() 和 wcrtomb())是线程安全的,但前提是您传入指向您自己的 mbstate_t 对象的指针。如果要在处理多字节字符串时确保线程安全,这些函数只能使用非 NULL 的 mbstate_t * 参数。
exit()即使提供了基本 _sys_exit()(实际终止所有线程)的实现,也不要在多线程程序中调用exit()。
在这种情况下,exit() 在调用 _sys_exit() 之前 先执行清除操作,因此会中断其他线程。
rand(), srand()这些函数保留全局性且不受保护的内部状态。 这意味着,rand() 调用从来都不是线程安全的。
ARM 建议您使用自己的锁定,以确保每次只有一个线程调用 rand(),例如,通过定义$Sub$$rand()(如果要避免更改代码)。
或者,也可以执行以下操作之一:
  • 提供您自己的随机数生成器,它可能具有多个独立实例
  • 硬性规定只有一个线程需要生成随机数。

[1] 已不提倡使用 gamma()。


继承事业,薪火相传
返回列表