[Win32] Issue with threads::shared and rand
Needs Triage
This is a follow up to what was previously reported in https://github.com/Perl/perl5/issues/24237, but that earlier report should remain closed, owing to it being inaccurate.
In a nutshell, beginning with perl-5.43.8, the 25 random values generated by test 25 (<code>Check that rand() is randomized in new threads</code>) of dist/threads/t/thread.t will possibly contain more than 2 collisions - thereby causing that one test to fail.
For perl 5.43.7 and earlier, I can produce no evidence that such a collision has ever occurred.
Here are 2 demo scripts - firstly one that doesn't use threads:
```
#no_bug.pl
use strict;
use warnings;
use threads; # loaded, but not used
use threads::shared; # loaded, but not used
my %rand;
rand(10);
for(1..25) { $rand{int(rand(10000000000))}++ }
for my $k (keys(%rand)) {print "$k: $rand{$k}\n"}
print "KEYS: ", scalar keys(%rand), "\n";
```
That script runs as it should. I have not been able to get it to produce anything other than 25 unique random values - even when run on perl-5.43.8 or later.
And the second script, that does use threads::shared:
```
#bug_thread.pl
# Based on dist/threads/t/thread.t
use strict;
use warnings;
use threads;
use threads::shared;
my %rand : shared;
rand(10);
threads->create( sub { $rand{int(rand(10000000000))}++ } ) foreach 1..25;
for my $k (keys(%rand)) {print "$k: $rand{$k}\n"}
print "KEYS: ", scalar keys(%rand), "\n";
$_->join foreach threads->list;
```
On perl-5.43.7 and earlier, that script also works fine - producing 25 unique random values.
But when I run it on perl-5.43.8 or later, it is quite common for there to be at least one collision.
For example, on a perl-5.43.10 built using a 64-bit mingw64 port of gcc-16.1.0 (mcf threading), here is one result of running that script :
```
D:\comp-1610-ucrt\perl-5.43.10>.\perl -I.\lib \pscrpt\bug_thread.pl
6217928974: 1
1898989855: 1
6763960880: 1
7575793178: 2
9905659938: 1
7937910580: 3
3929827383: 1
7812630194: 2
6731201760: 4
892703093: 1
6420137361: 1
7437356841: 3
3600733581: 1
8983539664: 1
1635413717: 1
KEYS: 16
```
The same issue arises with perls built with MSVC2022 and MSVC2026, and it applies to both 32-bit and 64-bit builds of perl.
(Some builds seem to be more severely compromised than others.)
In the 5.43.8 issue of perldelta.pod, I couldn't see anything about either "threads" or the "rand" function.
But there was one Windows-specific change mentioned: https://github.com/Perl/perl5/issues/4106.
I don't know whether that could be relevant.
Two observations about the dist/threads/t/thread.t test script:
1) Allowing test 25 to pass when there have been 2 collisions seems excessively lenient to me. IMO, that test should fail if there is only 1 collision.
2) I'm a bit puzzled by the <code>rand(10);</code> call in test 25 ... though I've a vague notion it might have been relevant to some of the perls of the last century.
UPDATE 1: A quick check, and it seems that cygwin is <b>not</b> subject to this issue.
All of these perls that I've tested are just fairly standard builds of perl.
Here is the <code>perl -V</code> for the perl-5.43.10 whose output I provided above:
```
D:\comp-1610-ucrt\perl-5.43.10>.\perl -I.\lib -V
Summary of my perl5 (revision 5 version 43 subversion 10) configuration:
Platform:
osname=MSWin32
osvers=10.0.26200.8457
archname=MSWin32-x64-multi-thread
uname=''
config_args='undef'
hint=recommended
useposix=true
d_sigaction=undef
useithreads=define
usemultiplicity=define
use64bitint=define
use64bitall=undef
uselongdouble=undef
usemymalloc=n
default_inc_excludes_dot=define
Compiler:
cc='gcc'
ccflags =' -DWIN32 -DWIN64 -fdiagnostics-color=never -fno-ident -DPERL_TEXTMODE_SCRIPTS -DMULTIPLICITY -DPERL_IMPLICIT_SYS -DUSE_PERLIO -D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing -mms-bitfields'
optimize='-O2'
cppflags='-DWIN32'
ccversion=''
gccversion='16.1.0'
gccosandvers=''
intsize=4
longsize=4
ptrsize=8
doublesize=8
byteorder=12345678
doublekind=3
d_longlong=define
longlongsize=8
d_longdbl=define
longdblsize=16
longdblkind=3
ivtype='long long'
ivsize=8
nvtype='double'
nvsize=8
Off_t='long long'
lseeksize=8
alignbytes=8
prototype=define
Linker and Libraries:
ld='g++'
ldflags ='-s -L"D:\perl-5.43.10-1610-ucrt-mcf\lib\MSWin32-x64-multi-thread\CORE" -L"C:\winlibs-ucrt-1610\mingw64\lib" -L"C:\winlibs-ucrt-1610\mingw64\x86_64-w64-mingw32\lib" -L"C:\winlibs-ucrt-1610\mingw64\lib\gcc\x86_64-w64-mingw32\16.1.0"'
libpth=C:\winlibs-ucrt-1610\mingw64\lib C:\winlibs-ucrt-1610\mingw64\x86_64-w64-mingw32\lib C:\winlibs-ucrt-1610\mingw64\lib\gcc\x86_64-w64-mingw32\16.1.0 D:\_64\msys_1610\1.0\local\lib
libs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
perllibs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
libc=-lucrt
so=dll
useshrplib=true
libperl=libperl543.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs
dlext=dll
d_dlsymun=undef
ccdlflags=' '
cccdlflags=' '
lddlflags='-shared -s -L"D:\perl-5.43.10-1610-ucrt-mcf\lib\MSWin32-x64-multi-thread\CORE" -L"C:\winlibs-ucrt-1610\mingw64\lib" -L"C:\winlibs-ucrt-1610\mingw64\x86_64-w64-mingw32\lib" -L"C:\winlibs-ucrt-1610\mingw64\lib\gcc\x86_64-w64-mingw32\16.1.0"'
Characteristics of this binary (from libperl):
Compile-time options:
HAS_LONG_DOUBLE
HAS_TIMES
HAVE_INTERP_INTERN
MULTIPLICITY
PERLIO_LAYERS
PERL_COPY_ON_WRITE
PERL_HASH_FUNC_SIPHASH13
PERL_HASH_USE_SBOX32
PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP
PERL_OP_PARENT
PERL_PRESERVE_IVUV
PERL_USE_SAFE_PUTENV
USE_64_BIT_INT
USE_ITHREADS
USE_LARGE_FILES
USE_LOCALE
USE_LOCALE_COLLATE
USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC
USE_LOCALE_TIME
USE_PERLIO
USE_PERL_ATOF
USE_THREAD_SAFE_LOCALE
Built under MSWin32
Compiled at May 27 2026 13:03:32
@INC:
.\lib
D:/comp-1610-ucrt/perl-5.43.10/lib
```
1 条评论