Создание случайных чисел в многопоточной программе на C - PullRequest
4 голосов
/ 07 января 2012

Я пишу программу, в которой есть рабочие потоки, которые создают случайные числа от 0 до 3 от 0 до x-1 (переменная)числа в C.

Я использую компилятор gcc и работаю в Ubuntu 11.10

Ответы [ 5 ]

7 голосов
/ 07 января 2012

rand() & srand() не являются безопасными в этом случае.

Они оба не являются ни входящими, ни безопасными .Вообще говоря, ни в стандартах C, ни в C ++ не предъявляются какие-либо требования в отношении безопасности потоков ни для одной из стандартных функций библиотеки.
Некоторые реализации действительно могут предоставлять поточно-ориентированные версии, но это не предусмотрено стандартом.

Чтобы иметь возможность использовать генератор случайных чисел в многопоточной среде Вам понадобится реализация, позволяющая переходить в состояние.Таким образом, вы можете сохранить одно значение состояния на поток и генерировать случайные числа хорошего качества без синхронизации.

Стандартная библиотека C не предоставляет никаких вариантов.Это делает 100% -ную переносимость практически невозможной. Выбор использования будет зависеть от вашей среды, которую вы должны упомянуть как часть вашего вопроса, чтобы получить точные ответы.

Посмотрите на GNUНаучная библиотека , которая утверждает, что обеспечивает Многопоточный генератор случайных чисел .

1 голос
/ 26 марта 2014

Если вам просто нужны какие-то случайные числа, и вам все равно, генерируются ли случайные числа независимо или нет, вы все равно можете использовать rand() и srand().

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

    void* cb1(void*) {                        
        while(1) {                            
            printf("cb1, rand:%d\n",rand());  
            sleep(1);                         
        }                                     
    }                                         

    void* cb2(void*) {                        
        while(1) {                            
            printf("cb2, rand:%d\n",rand());  
            sleep(1);                         
        }                                     
    }                                         


    int main() {                              
        pthread_t  th1, th2;                  
        srand(1);                             
        pthread_create(&th1, NULL, cb1, NULL);
        pthread_create(&th2, NULL, cb2, NULL);

        pthread_join(th1, NULL);              
        pthread_join(th2, NULL);              

        return 0;                             
    }                                         
1 голос
/ 07 января 2012

Использовать rand_r() (см. Rand (3))

Функция rand_r () снабжена указателем на unsigned int, который будет использоваться в качестве состояния.

Он является реентерабельным и принимает семя в качестве входных данных, поэтому потоки могут управлять своими семенами отдельно.

0 голосов
/ 08 января 2012

Простая версия без проверки ошибок с использованием C11 threads.h будет выглядеть так:

mtx_t rand_mtx;

//run only once.
int rand_init(int seed)
{
     srand(seed);
     mtx_init(&rand_mtx, mtx_plain);
} 

int synced_rand()
{
    mtx_lock(&rand_mtx);
    int r = rand();
    mtx_unlock(&rand_mtx);
    return r;
}
0 голосов
/ 07 января 2012

Истина и красота;

http://en.wikipedia.org/wiki/Mersenne_twister

Напишите свой собственный ГСЧ.

(Извинения. Я только что посмотрел эту вики-страницу. ПоследнийНекоторое время назад я посмотрел, все было в порядке, вы могли прочитать его и реализовать твистер. Теперь это набор математик уровня, который абсолютно никому ничего не объясняет, за исключением подгруппы людей, которые четыре года проучились в университете, изучая математику.Я вижу, что это часто случается в вики: - (

...