C语言标准库函数rand与多线程

标签: , , , ,

今天在一个多线程程序中调用了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,于是用该函数测试了一下,貌似是线程安全的。

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. 用JavaScript读写二进制文件的另一种方法
  2. InputBox与两数相加——一个简单的VBS脚本问题
  3. OpenWrt配置IPv6之6to4隧道
  4. VBS基础教程第五篇
  5. Raspberry Pi -bash: nslookup: command not found

2 条评论 发表在“C语言标准库函数rand与多线程”上

  1. mooc说道:

    也可以手动用线程同步处理下

  2. pythontree说道:

    rand随机数需要初始化随机数发生器,好像是srand函数

mooc 留下回复