random is not multithread-safe in Cygwin
Brian Inglis
Brian.Inglis@Shaw.ca
Mon Nov 13 17:34:43 GMT 2023
On 2023-11-13 09:12, Corinna Vinschen via Cygwin wrote:
> On Nov 10 17:19, Bruno Haible via Cygwin wrote:
>> The function 'random' is, unlike 'rand', not marked as not MT-safe in POSIX
>> [1][2]. Thus it must be multithread-safe [3]:
>> "Each function defined in the System Interfaces volume of POSIX.1-2017
>> is thread-safe unless explicitly stated otherwise."
>> And indeed glibc, musl libc, AIX, Android, and even NetBSD implement it in a
>> multithread-safe way.
> Our code is from FreeBSD, originally. I checked the latest code from
> FreeBSD. It doesn't lock anything in random() and generates the same
> error when running the same test app.
> Why is that ok for FreeBSD?
It appears that random(3) is intended to provide a single random series during
execution of a program with simple needs; behaviour is not reproducible when
threaded, says POSIX, newlib, and Linux (below).
From POSIX The Open Group Base Specifications Issue 7, 2018 edition IEEE Std
1003.1-2017 Volume 2: System Interfaces and initstate(3p) to which random(3p)
refers and defers but does not link or .so:
"NAME
random — generate pseudo‐random number
SYNOPSIS
#include <stdlib.h>
long random(void);
DESCRIPTION
Refer to initstate()."
* That's all folks!
"NAME
initstate, random, setstate, srandom - pseudo-random number functions
...
APPLICATION USAGE
...
Threaded applications should use erand48(), nrand48(), or jrand48() instead of
random() when an independent random number sequence in multiple threads is
required."
From newlib:
"NAME
random, srandom - pseudo-random numbers
...
NOTES
random and srandom are unsafe for multi-threaded applications.
_XOPEN_SOURCE may be any value >= 500.
PORTABILITY
random is required by XSI. This implementation uses the same algorithm
as rand."
* Newlib, and presumably FreeBSD, do not support initstate, setstate, or > 8
(for amd64/x86_64) bytes state.
From man-pages-linux random(3):
"CAVEATS
...
The random() function should not be used in multithreaded programs where
reproducible behavior is required.
Use random_r(3) for that purpose."
* As usual, random_r(3) requires the caller to provide an initialized state
vector buffer (of 8-256 bytes), allowing the caller to decide the amount of
randomness and scope of the random series, and possibly call initstate_r(3), to
control the seed.
--
Take care. Thanks, Brian Inglis Calgary, Alberta, Canada
La perfection est atteinte Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add
mais lorsqu'il n'y a plus rien à retirer but when there is no more to cut
-- Antoine de Saint-Exupéry
More information about the Cygwin
mailing list