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