线程不安全函数

多线程编程时一定要注意这样的问题,出了bug很难定位。


以下内容转自:http://www.keil.com/support/man/docs/armlibref/armlibref_Chddjdaj.htm

Table 2. Functions that are not thread-safe


Functions Description
asctime(),


localtime(),


strtok()


These functions are all thread-unsafe. Each contains a static buffer that might be overwritten by another thread between a call to the function and the subsequent use of its return value.


ARM supplies reentrant versions, _asctime_r(), _localtime_r(), and _strtok_r(). ARM recommends that you use these functions instead to ensure safety.


Note
These reentrant versions take additional parameters. _asctime_r() takes an additional parameter that is a pointer to a buffer that the output string is written into. _localtime_r() takes an additional parameter that is a pointer to a struct tm, that the result is written into. _strtok_r() takes an additional parameter that is a pointer to a char pointer to the next token.
exit()
Do not call exit() in a multithreaded program even if you have provided an implementation of the underlying _sys_exit() that actually terminates all threads.


In this case, exit() cleans up before calling _sys_exit() so disrupts other threads.


gamma(), [a]


lgamma(),


lgammaf(),


lgammal()


These extended mathlib functions use a global variable, _signgam, so are not thread-safe.
mbrlen(),


mbsrtowcs(),


mbrtowc(),


wcrtomb(),


wcsrtombs()


The C89 multibyte conversion functions (defined in stdlib.h) are not thread-safe, for example mblen() and mbtowc(), because they contain internal static state that is shared between all threads without locking.


However, the extended restartable versions (defined in wchar.h) are thread-safe, for example mbrtowc() and wcrtomb(), provided you pass in a pointer to your own mbstate_t object. You must exclusively use these functions with non-NULL mbstate_t * parameters if you want to ensure thread-safety when handling multibyte strings.


rand(), srand()
These functions keep internal state that is both global and unprotected. This means that calls to rand() are never thread-safe.


ARM recommends that you do one of the following:


Use the reentrant versions _rand_r() and _srand_r() supplied by ARM. These use user-provided buffers instead of static data within the C library.


Use your own locking to ensure that only one thread ever calls rand() at a time, for example, by defining $Sub$$rand() if you want to avoid changing your code.


Arrange that only one thread ever needs to generate random numbers.


Supply your own random number generator that can have multiple independent instances.


Note
_rand_r() and _srand_r() both take an additional parameter that is a pointer to a buffer storing the state of the random number generator.
setlocale(), localeconv()


setlocale() is used for setting and reading locale settings. The locale settings are global across all threads, and are not protected by a lock. If two threads call setlocale() to simultaneously modify the locale settings, or if one thread reads the settings while another thread is modifying them, data corruption might occur. Also, many other functions, for example strtod() and sprintf(), read the current locale settings. Therefore, if one thread calls setlocale() concurrently with another thread calling such a function, there might be unexpected results.


Multiple threads reading the settings simultaneously is thread-safe in simple cases and if no other thread is simultaneously modifying those settings, but where internally an intermediate buffer is required for more complicated returned results, unexpected results can occur unless you use a reentrant version of setlocale().


ARM recommends that you either:


Choose the locale you want and call setlocale() once to initialize it. Do this before creating any additional threads in your program so that any number of threads can read the locale settings concurrently without interfering with one another.


Use the reentrant version _setlocale_r() supplied by ARM. This returns a string that is either a pointer to a constant string, or a pointer to a string stored in a user-supplied buffer that can be used for thread-local storage, rather than using memory within the C library.


Be aware that _setlocale_r() is not fully thread-safe when accessed concurrently to change locale settings. This access is not lock-protected.


Also, be aware that localeconv() is not thread-safe. Call the ARM function _get_lconv() with a pointer to a user-supplied buffer instead.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值