MST

星途 面试题库

面试题:C语言随机数函数在多线程环境下的应用

假设你在一个多线程的C语言程序中需要使用随机数,描述一下使用标准库的随机数函数(如rand())可能会遇到的问题,并提出至少一种解决方案,同时编写一段简单的多线程代码示例,展示你提出的解决方案的实现。
40.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

使用rand()在多线程中可能遇到的问题

  1. 线程安全问题:标准库的rand()函数不是线程安全的。在多线程环境下,多个线程同时调用rand()可能会导致竞争条件,因为rand()通常依赖于一个内部的静态状态(如种子),多个线程同时访问和修改这个静态状态会产生未定义行为。

解决方案

  1. 每个线程使用独立的种子:为每个线程生成一个独立的种子,这样每个线程就有自己独立的随机数生成序列,避免了竞争。可以使用线程局部存储(TLS)来实现。

代码示例

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

// 线程局部存储变量,每个线程有自己独立的种子
_Thread_local unsigned int seed;

// 线程执行函数
void* generate_random(void* arg) {
    // 使用线程ID作为种子的一部分生成唯一种子
    long thread_id = (long)arg;
    seed = (unsigned int)(time(NULL) + thread_id);

    // 生成并打印10个随机数
    for (int i = 0; i < 10; ++i) {
        int random_number = rand_r(&seed) % 100;
        printf("Thread %ld: Random number %d: %d\n", thread_id, i, random_number);
    }

    return NULL;
}

int main() {
    const int num_threads = 3;
    pthread_t threads[num_threads];

    // 创建线程
    for (long i = 0; i < num_threads; ++i) {
        if (pthread_create(&threads[i], NULL, generate_random, (void*)i) != 0) {
            perror("pthread_create");
            return 1;
        }
    }

    // 等待所有线程完成
    for (int i = 0; i < num_threads; ++i) {
        if (pthread_join(threads[i], NULL) != 0) {
            perror("pthread_join");
            return 2;
        }
    }

    return 0;
}

在这段代码中:

  • 使用_Thread_local关键字声明了一个线程局部变量seed,每个线程都有自己独立的种子。
  • 在每个线程的执行函数generate_random中,根据线程ID和当前时间为每个线程生成唯一的种子。
  • 使用rand_r函数来生成随机数,rand_rrand的线程安全版本,它需要一个指向种子的指针作为参数。
  • main函数中创建多个线程并等待它们完成。