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