请教关于Perl (use threads) 的一个小问题

请教关于Perl (use threads) 的一个小问题

这两天开始看一下Perl 的Multi-thread.

以下代码是从perldoc perlthrtut 中copy出来的,但是在我的本地测试中并不会hang (windows 和 Linux).

    use threads;

    my $a : shared = 4;
    my $b : shared = "foo";
    my $thr1 = threads->new(sub {
        lock($a);
        sleep 20;
        lock($b);
    });
    my $thr2 = threads->new(sub {
        lock($b);
        sleep 20;
        lock($a);
    });

This program will probably hang until you kill it.  The only way it won’t hang is if one of the two threads acquires both locks first.  A guaran‐
teed-to-hang version is more complicated, but the principle is the same.


简单起见:
如下Code:
  use threads;
  use threads::shared;
  
  my $total : shared = 0;
  
  lock($total);
  lock($total);

同样也不会Hang.


********************************************************

请问,这是因为我用的Perl不支持lock还是因为我用的Code有问题?
有人能给个建议吗?  谢谢!
********************************************************




附:
Perl Windows Version:
C:\>perl -v
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 50 registered patches, see perl -V for more detail)

Copyright 1987-2006, Larry Wall

Binary build 820 [274739] provided by ActiveState http://www.ActiveState.com
Built Jan 23 2007 15:57:46

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

C:\>perl -V

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cl', ccflags ='-nologo -GF -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT
-DNO_HASH_SEED -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_R
EADFIX',
    optimize='-MD -Zi -DNDEBUG -O1',
    cppflags='-DWIN32'
    ccversion='12.00.8804', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf  -libpath:"C:\Perl\lib\CORE"  -machine:x8
6'
    libpth=\lib
    libs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.li
b ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp3
2.lib msvcrt.lib
    perllibs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell3
2.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odb
ccp32.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf  -libpath:"C:\Perl\lib\CORE"
-machine:x86'


Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT
                        PERL_IMPLICIT_SYS PERL_MALLOC_WRAP
                        PL_OP_SLAB_ALLOC USE_ITHREADS USE_LARGE_FILES
                        USE_PERLIO USE_SITECUSTOMIZE
  Locally applied patches:
        ActivePerl Build 820 [274739]
        Iin_load_module moved for compatibility with build 806
        PerlEx support in CGI::Carp
        Less verbose ExtUtils::Install and Pod::Find
        Patch for CAN-2005-0448 from Debian with modifications
        Rearrange @INC so that 'site' is searched before 'perl'
        Partly reverted 24733 to preserve binary compatibility
        29930 win32.c typo in #define MULTIPLICITY
        29868 win32_async_check() can still loop indefinitely
        29690,29732 ANSIfy the PATH environment variable on Windows
        29689 Add error handling to win32_ansipath
        29675 Use short pathnames in $^X and @INC
        29607,29676 allow blib.pm to be used for testing Win32 module
        29605 Implement killpg() for MSWin32
        29598 cwd() to return the short pathname
        29597 let readdir() return the alternate filename
        29590 Don't destroy the Unicode system environment on Perl startup
        29528 get ext/Win32/Win32.xs to compile on cygwin
        29509,29510,29511 Move Win32::* functions into Win32 module
        29483 Move Win32 from win32/ext/Win32 to ext/Win32
        29481 Makefile.PL changes to compile Win32.xs using cygwin
        28671 Define PERL_NO_DEV_RANDOM on Windows
        28376 Add error checks after execing PL_cshname or PL_sh_path
        28305 Pod::Html should not convert "foo" into ``foo''
        27833 Change anchor generation in Pod::Html for '=item item 2'
        27832,27847 fix Pod::Html::depod() for multi-line strings
        27719 Document the functions htmlify() and anchorify() in Pod::Html
        27619 Bug in Term::ReadKey being triggered by a bug in Term::ReadLine
        27549 Move DynaLoader.o into libperl.so
        27528 win32_pclose() error exit doesn't unlock mutex
        27527 win32_async_check() can loop indefinitely
        27515 ignore directories when searching @INC
        27359 Fix -d:Foo=bar syntax
        27210 Fix quote typo in c2ph
        27203 Allow compiling swigged C++ code
        27200 Make stat() on Windows handle trailing slashes correctly
        27133 Initialise lastparen in the regexp structure
        27061 L<PerlIO> and Pod::Html
        27034 Avoid "Prototype mismatch" warnings with autouse
        26970 Make Passive mode the default for Net::FTP
        26921 Avoid getprotobyname/number calls in IO::Socket::INET
        26897,26903 Make common IPPROTO_* constants always available
        26670 Make '-s' on the shebang line parse -foo=bar switches
        26637 Make Borland and MinGW happy with change 26379
        26536 INSTALLSCRIPT versus INSTALLDIRS
        26379 Fix alarm() for Windows 2003
        26087 Storable 0.1 compatibility
        25861 IO::File performace issue
        25084 long groups entry could cause memory exhaustion
        24699 ICMP_UNREACHABLE handling in Net::Ping
  Built under MSWin32
  Compiled at Jan 23 2007 15:57:46
  @INC:
    C:/Perl/site/lib
    C:/Perl/lib
    .


Perl Linux Version:
root@Eleswen:/# perl -v

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

Copyright 1987-2006, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.


root@Eleswen:/# perl -V
Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=linux, osvers=2.6.15.7, archname=i486-linux-gnu-thread-multi
    uname='linux terranova 2.6.15.7 #1 smp thu jul 12 14:27:56 utc 2007 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.6.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8
    gnulibc_version='2.6.1'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'


Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT
                        PERL_MALLOC_WRAP THREADS_HAVE_PIDS USE_ITHREADS
                        USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API
  Built under linux
  Compiled at Dec  4 2007 08:56:39
  @INC:
    /etc/perl
    /usr/local/lib/perl/5.8.8
    /usr/local/share/perl/5.8.8
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.8
    /usr/share/perl/5.8
    /usr/local/lib/site_perl
    .

# 开头改成

   use threads;
    use threads::shared;

#

#

#

#


#结尾添加

sleep 50



应该可以从任务管理器里看出效果

第二个例子是概念错误,同一个代码块lock多次没意义

明白了。

加上:
use threads::shared;

结尾改成:
$thr1-join();
$thr2-join();

就可以了。

非常感谢!