rand_r은 스레드로부터 안전하지만 재 입력 가능합니다.
아래 코드는 xorshift 알고리즘을 사용하여 uint128_t pseuso 난수를 생성합니다.
.H : #ifndef UINTX_TYPES_H_INCLUDED
#define UINTX_TYPES_H_INCLUDED
#include <inttypes.h>
#include <ctype.h>
typedef __uint128_t uint128_t;
typedef __uint64_t uint64_t;
#define UINT128_C(hi, lo) (((uint128_t)(hi) << 64) | (uint128_t)(lo))
#define UINT128_MIN UINT128_C(0x0000000000000000, 0x0000000000000000)
#define UINT128_0 UINT128_MIN
#define UINT128_MAX (~(UINT128_0) - 1)
#endif // UINTX_TYPES_H_INCLUDED
lf.h :
#ifndef LF_H_INCLUDED
#define LF_H_INCLUDED
#define AAF(ADDR, VAL) __sync_add_and_fetch((ADDR), (VAL))
#endif // LF_H_INCLUDED
rand.h :
#ifndef RAND_H_INCLUDED
#define RAND_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include "lf.h"
#include "uintx_types.h"
#define URANDOM "/dev/random"
void srand_init(void);
uint128_t rand_range_128(uint128_t min, uint128_t max);
#endif // RAND_H_INCLUDED
rand.c :
#include "rand.h"
uint64_t r[2];
uint64_t xorshift64star(int index)
{
uint64_t x;
x = r[index];
x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
x = x * UINT64_C(2685821657736338717);
return AAF(&r[index], x);
}
void srand_init(void)
{
struct timespec ts;
size_t nbytes;
ssize_t bytes_read;
int fd;
clock_gettime(CLOCK_REALTIME, &ts);
r[0] = (uint64_t)(ts.tv_sec * 1.0e9 + ts.tv_nsec);
xorshift64star(0);
if ((fd = open(URANDOM, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH)) == -1)
{
r[1] = r[0] + 1;
xorshift64star(1);
}
else
{
nbytes = sizeof(r[1]);
bytes_read = read(fd, &r[1], nbytes);
if ((bytes_read == 0) || (r[1] == 0ull))
{
r[1] = r[0] + 1;
xorshift64star(1);
}
close(fd);
}
}
uint64_t rand_64(void)
{
return xorshift64star(0);
}
uint128_t rand_128(void)
{
uint128_t r;
r = xorshift64star(0);
r = (r << 64) | xorshift64star(1);
return r;
}
uint128_t rand_range_128(uint128_t min, uint128_t max)
{
return (rand_128() % (max+1-min))+min;
}
TEST.C :
0,123,172,057,313, Linux에서 gcc (4.9.2)로 컴파일하십시오. 내가 즉 정규 분포에이 기능을 맞춤에 의해 생성 된 번호는이 기능이있는 경우 만약 내가 정말하지는 알고 말을 여기
size_t random_between_range(size_t min, size_t max){
unsigned short state[3];
unsigned int seed = time(NULL) + (unsigned int) pthread_self();
memcpy(state, &seed, sizeof(seed));
return min + nrand48(state) % (max - min);
}
:처럼이 기능을 사용할 수 있습니다 리눅스 시스템에서
시퀀스가 결정적 이길 원합니까? - http://stackoverflow.com/questions/6467585/deterministic-random-number-generator-tied-to-instance-thread-independent/6467623#6467623 – Flexo
특별한 요구 사항이 없다면'rand_r'을 사용하십시오. –
rand()는 리눅스에서는 thread safe하지만, posix는 그 목적을 위해 rand_r을 제공하지만 반드시 그렇게 할 필요는 없다. glibc는 rand()에 내부 뮤텍스를 사용합니다. 스레드가 많은 난수를 생성 할 경우 경합을 일으킬 수 있습니다. – nos