여러 스레드에서 stdlib의 rand() 사용
몇 개의 스레드가 모두 같은 기능을 수행합니다.이들 각각에서 서로 다른 난수를 여러 번 생성합니다.이렇게 하려고 했는데srand(time(0))
처음에는 다 같은 번호인 것 같아요.
전화해야 하나요?srand(time(0))
프로그램당 1회(즉, 시작 시)만main
(예를 들어, 여러 번 호출된 각 함수의 시작 부분에서) 또는 다른 무엇인가가 있습니까?
srand()는 난수 생성기를 시드합니다.전화만 하면 됩니다.srand(time(NULL))
기동시에 1회.
즉, 문서에는 다음과 같이 기술되어 있습니다.
함수
rand()
는 각 콜에서 변경된 숨김 상태를 사용하기 때문에 재진입 또는 스레드 세이프가 아닙니다.이 값은 다음 콜에서 사용하는 시드 값일 수도 있고 더 정교한 값일 수도 있습니다.스레드 애플리케이션에서 재현 가능한 동작을 얻으려면 이 상태를 명시해야 합니다.함수rand_r()
에 대한 포인터와 함께 제공됩니다.unsigned int
, 상태로 사용합니다.이는 매우 적은 양의 상태이므로 이 함수는 약한 의사 랜덤 생성기가 됩니다.대신 (3)을 시도합니다.
위의 강조된 부분은 아마도 모든 스레드가 동일한 번호를 받는 이유일 것입니다.
C는 멀티스레딩용으로 설계되지 않았기 때문에 멀티스레딩을 사용하는 srand()의 동작은 정의되지 않으며 C 런타임라이브러리에 의존합니다.
많은 Unix/Linux C 런타임 라이브러리는 단일 정적 상태를 사용합니다.이러한 상태에서는 여러 스레드에서 srand() 및 rand()를 전혀 사용할 수 없습니다.다른 Unix C 런타임은 다르게 동작할 수 있습니다.
Visual C++ 런타임은 스레드 단위의 내부 상태를 사용하기 때문에 각 스레드에 대해 srand()를 호출하는 것이 안전합니다.그러나 Neil이 지적한 바와 같이, 모든 스레드는 동일한 값으로 시드될 것입니다. 즉, (time + thread-id)로 시드됩니다.
물론 휴대성을 위해 rand 함수가 아닌 랜덤 객체를 사용하면 숨겨진 상태에 전혀 의존하지 않습니다.스레드당 1개의 오브젝트가 필요하며 각 오브젝트에 (time + thread-id)를 시드하는 것도 좋은 방법입니다.
C 가 아닌 C++ 를 사용하고 있기 때문에, c++11 을 사용하면, srand/rand 와 관련된 스레드 문제를 회피할 수 있습니다.이러한 기능을 지원하는 최신 컴파일러를 사용하는지 여부에 따라 달라집니다.각 스레드에 별도의 엔진과 배전을 사용합니다.그 예는 주사위처럼 작용한다.
#include <random>
#include <functional>
std::uniform_int_distribution<int> dice_distribution(1, 6);
std::mt19937 random_number_engine; // pseudorandom number generator
auto dice_roller = std::bind(dice_distribution, random_number_engine);
int random_roll = dice_roller(); // Generate one of the integers 1,2,3,4,5,6.
나는 이 질문에 대답할 때 위키피디아 C++11과 Boost random을 참조했다.
man 페이지부터:
rand() 함수는 각 콜에서 변경된 숨김 상태를 사용하기 때문에 재진입 또는 스레드 세이프가 아닙니다.
따라서 나사산 코드와 함께 사용하지 마십시오.rand_r
(또는 Linux/glibc를 사용하는 경우).각 RNG를 다른 값으로 시드합니다(메인 스레드에 첫 번째 RNG를 시드하여 각 스레드에 있는 RNG에 랜덤시드를 생성할 수 있습니다).
모든 스레드를 동시에 실행하는 경우 srand로 전송되는 시간은 각 스레드에서 동일합니다.그들은 모두 같은 씨앗을 가지고 있기 때문에, 모두 같은 시퀀스를 가지고 있다.로컬 변수의 메모리 주소 같은 다른 주소를 사용해 보십시오.
그것은 좋은 질문이네요.더 큰 문제가 있는 것 같아서 바로 대답할 수 없어요.랜드가 안전하다는 사실조차 확실치 않은 것 같아.내부 상태를 유지하며 프로세스별 또는 스레드별인지, 스레드 안전인지 프로세스별인지 명확하게 정의되지 않은 것 같습니다.
각 액세스 주위에 뮤텍스를 잠글 수 있도록 합니다.
또는 가능하면 부스트로부터의 생성과 같은 보다 명확한 생성 사용
언급URL : https://stackoverflow.com/questions/6161322/using-stdlibs-rand-from-multiple-threads
'sourcecode' 카테고리의 다른 글
변환에서 푸시할 때 Vuex 저장소에서 구성 요소 컬렉션을 업데이트하지 않음 (0) | 2022.08.07 |
---|---|
타입 번호의 입력에 대해서, 증감 처리를 덮어쓰는 방법이 있습니까? (0) | 2022.08.03 |
실제 예에서는 dup 또는 dup2를 사용합니다. (0) | 2022.08.03 |
사용되지 않는 함수 매개 변수 값을 void로 캐스팅하는 이유는 무엇입니까? (0) | 2022.08.03 |
C의 구조 크기 (0) | 2022.08.03 |