Joshua Kronengold wrote:
> 
> Sampo Kellomaki writes:
> >I'm a bit new to threaded perl, but I have noticed following
> >obstacles in writing thread safe code for perl
> >       * file handles can't be made "my"
> Incorrect.  perldoc Filehandle.

Thanks for pointing me in right way. Now if I could know if the object
interface is really thread safe or if it in the innards uses local
variables which are not thread safe. Documentation does not discuss
this.

> >       * local variables can not be safely used in threaded code
> >         (another thread can unexpectedly unlocalize your local
> >          variable in middle of a basic block)
> 
> I confess that I'm not sure how local variables work in threads; by
> all rights, they -should- be semaphored, but I don't know that they
> are.

Consider this piece if code

        use Thread;

        $a = 'aaa';
        $_ = 'ccc';

        sub f {
            sleep 1;
            print "F1: $a,$_\n";
            local $a = 'foo';
            local $_ = 'DDD';
            print "F2: $a,$_\n";
        }

        sub b {
            print "B1: $a,$_\n";
            local $a = 'bar';
            local $_ = 'EEE';
            print "B2: $a,$_\n";
            sleep 2;
            print "B3: $a,$_\n";
        }

        new Thread \&f;
        &b;

which produces this output

        B1: aaa,ccc
        B2: bar,EEE
        F1: bar,ccc
        F2: foo,DDD
        B3: bar,EEE

As you can see, B1 sees the global values. B2 sees local values (because
f is still sleeping), but F1 sees b's local $a and global $_. This
is not consistent. In my opinion $_ behaved correctly while $a
is broken. At F2 everything is dandy because b didn't get to interfere.
At B3 all is OK, too, though probably be luck because f ran entirely
during b's sleep so $a got localized from broken value and then
delocalized back to the right value, which made everything look OK for
b.

So from this test I can answer my concerns about map and grep: yes it
seems $_ has special magical treatment so localization is thread safe.
I'd like to know if there is some consistent effort in threaded perl
to make some classes of constructs thread safe. The fact that some
local variables are safe, while others are not, is not very reassuring.

> >       * behaviour of magic variables is not well defined
> 
> Sure it is.  You can localize them (and they are automagically
> localized when appropriate), but can't create lexical variables with
> their names.
> 
> >, e.g. $_ can't be made "my" but its used by many very important
> >         perl constructs, such as map and grep.
> 
>         A decent, but not great workaround would be to -always- create
> lexical placeholders for magic variables, ie @foobar=map {my ($foo)=$_;
> $foo=~s/f/b/gi; $foo } @bar.

I do not think that would work. It only narrows the window for race
but does not eliminate it. Never-the-less, it seems $_ luckily is
safe.

>         But in general, separate local variables with the same name
> should not bash each other in threads.  I don't know that this is how
> things actually work.

It seems it only works for certain magical locals, like $_. Its broken
for regular locals.

> >         must be magically thread safe (although $_ can't be made
> >         local?!?)
            ^^^^^

I meant "my". Sorry.

> It can too.

BTW, I'm using perl compiled thusly (but the broken behaviour repeats
under linux-threads as well):

perl -V
Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
  Platform:
    osname=solaris, osvers=2.6, archname=sun4-solaris-thread
    uname='sunos hippo 5.6 generic_105181-15 sun4u sparc sunw,ultra-5_10
'
    hint=previous, useposix=true, d_sigaction=define
    usethreads=define useperlio=undef d_sfio=undef
  Compiler:
    cc='gcc', optimize='-g', gccversion=2.7.2.3
    cppflags='-DMULTIPLICITY -D_REENTRANT -DDEBUGGING
-I/usr/local/include'
    ccflags ='-DMULTIPLICITY -D_REENTRANT -DDEBUGGING
-I/usr/local/include'
    stdchar='unsigned char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    alignbytes=8, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldl -lm -lposix4 -lpthread -lc -lcrypt
    libc=/lib/libc.so, so=so, useshrplib=true, libperl=libperl.so
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -R
/opt/tps/perl/thread-debug/lib/5.00503/sun4-solaris-thread/CORE'
    cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib'


Characteristics of this binary (from libperl): 
  Compile-time options: DEBUGGING MULTIPLICITY
  Built under solaris
  Compiled at Mar 30 2000 18:43:13
  @INC:
    /opt/tps/perl/thread-debug/lib/5.00503/sun4-solaris-thread
    /opt/tps/perl/thread-debug/lib/5.00503
    /opt/tps/perl/thread-debug/lib/site_perl/5.005/sun4-solaris-thread
    /opt/tps/perl/thread-debug/lib/site_perl/5.005
    .

--Sampo

S/MIME Cryptographic Signature

Reply via email to