ITADN
Perl/perl5/Issues

[Win32] Issue with threads::shared and rand

#24446Opensisyphus 创建于 2026-05-27
Needs Triage
S
sisyphuscommented
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 条评论