标题: C语言标准库函数rand与多线程
作者: Demon
链接: https://demon.tw/programming/c-rand-multi-thread.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
今天在一个多线程程序中调用了C标准库函数rand,结果却发现每个线程生成的随机数都是一样的,甚至每次运行程序生成的随机数都是一样的。
可以用下面的小程序模拟一下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
/*********************************************************/
/* By Demon */
/* https://demon.tw */
/*********************************************************/
#define N 10
HANDLE hThreads[N];
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
int n = rand();
printf("%d\n", n);
return 0;
}
int main() {
int i;
srand(time(NULL));
for (i = 0; i < N; ++i) {
hThreads[i] = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
}
WaitForMultipleObjects(N, hThreads, TRUE, INFINITE);
return 0;
}
通过测试可以知道rand函数不是线程安全的,搜索了一下,Linux文档是这样说的:
The function rand() is not reentrant or thread-safe, since it uses hidden state that is modified on each call. This might just be the seed value to be used by the next call, or it might be something more elaborate. In order to get reproducible behaviour in a threaded application, this state must be made explicit. The function rand_r() is supplied with a pointer to an unsigned int, to be used as state. This is a very small amount of state, so this function will be a weak pseudo-random generator. Try drand48_r(3) instead.
而MSDN上关于rand函数的文档完全没有提及线程安全,只是说有一个更安全的函数rand_s,于是用该函数测试了一下,貌似是线程安全的。
赞赏微信赞赏支付宝赞赏
随机文章:
也可以手动用线程同步处理下
rand随机数需要初始化随机数发生器,好像是srand函数