You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中srand结合pthread生成重复随机数的原因咨询

多线程生成重复随机数的问题解析

问题描述

我编写了一段通过多线程生成0到99之间随机数的简单C语言代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

void * NumGen(void * tid){
    int a = 0;
    a = rand() % 100;
    printf("a: %d\n",a);
};

int main()
{
    srand(time((NULL)));
    pthread_t tid0;
    pthread_t tid1;
    pthread_t tid2;
    pthread_t * pthreads[] = {&tid0,&tid1,&tid2};

    for (int i = 0; i < 3; i++)
        pthread_create(pthreads[i],NULL,NumGen,NULL);

    pthread_join(tid0, NULL);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

尽管调用了srand(time(NULL))初始化随机种子,但运行后输出结果为:

a: 41
a: 41
a: 41

请问为何无法生成不同的随机数?

核心原因

rand()是线程不安全的函数,它内部依赖一个全局的静态状态变量来生成下一个随机数。当三个线程几乎同时启动并调用rand()时,它们会在这个全局状态更新前读取到相同的值,最终生成完全一样的随机数。

虽然你在主线程初始化了种子,但线程启动的时间间隔极短(远小于time(NULL)的1秒精度),不过这不是主要问题——本质还是全局状态的竞争导致多个线程拿到了相同的初始随机状态。

解决办法

1. 为每个线程单独初始化随机种子

给每个线程分配独立的种子,结合线程ID、时间戳等唯一标识来避免重复:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

void * NumGen(void * tid){
    // 用线程ID+当前时间组合成唯一种子
    unsigned int seed = (unsigned int)pthread_self() ^ (unsigned int)time(NULL);
    srand(seed);
    int a = rand() % 100;
    printf("线程%ld生成: a = %d\n", (long)tid, a);
    return NULL;
};

int main()
{
    pthread_t tid0, tid1, tid2;
    pthread_t * pthreads[] = {&tid0, &tid1, &tid2};

    for (long i = 0; i < 3; i++)
        pthread_create(pthreads[i], NULL, NumGen, (void*)i);

    pthread_join(tid0, NULL);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

2. 使用线程安全的随机函数

如果你的系统支持POSIX标准,可以用rand_r()——它要求每个线程维护自己的随机状态,避免全局竞争:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

void * NumGen(void * tid){
    unsigned int seed = (unsigned int)pthread_self() ^ (unsigned int)time(NULL);
    // 每个线程用自己的状态变量调用rand_r
    int a = rand_r(&seed) % 100;
    printf("线程%ld生成: a = %d\n", (long)tid, a);
    return NULL;
};

int main()
{
    pthread_t tid0, tid1, tid2;
    pthread_t * pthreads[] = {&tid0, &tid1, &tid2};

    for (long i = 0; i < 3; i++)
        pthread_create(pthreads[i], NULL, NumGen, (void*)i);

    pthread_join(tid0, NULL);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

内容的提问来源于stack exchange,提问作者idop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 21:12:04