Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Does the :locked attribute not work under 5.8.0? For example, I expected the following
$ perl -Mthreads -le \ > 'sub f :locked {print $_[0]; sleep 2; print $_[0];} > threads->create(\&f, $_) for @ARGV; > $_->join() for threads->list()' foo bar
always to print "foo\nfoo\nbar\nbar\n", just as if I'd manually lock()ed a shared variable at the start of the sub. Instead, the f() calls run on top of each other. (e.g. - foo bar foo bar)
This happens both with redhat's perl-5.8.0-55 and with perl-5.8.1-RC5 on linux 2.4 -- and, yes, $Config{useithreads} eq "define" :)
|
|---|
| Replies are listed 'Best First'. | |||||||
|---|---|---|---|---|---|---|---|
|
Re: (ithreads) :locked subs
by liz (Monsignor) on Sep 24, 2003 at 09:05 UTC | |||||||
Still looking at a way to have Perl bomb at compilation when using the "locked" attribute in ithreads. Even if I would find it, I doubt whether Jarkko will allow it this late in the release game ;-( Liz
Update: die at compilation time with: if your Perl was compiled with ithreads support. As this (small) change to toke.c broke quite a number of tests when testing a threaded perl, I needed to patch 5 test-files to fix the errors. Therefore, I'm doutbful whether it will get included in 5.8.1.
Update: | [reply] [d/l] [select] | ||||||
|
Re: (ithreads) :locked subs
by BrowserUk (Patriarch) on Sep 24, 2003 at 06:56 UTC | |||||||
I *think* that it is safe to say that the locked attribute is a pthreads throwover that doesn't serve any purpose with ithreads. When you spawn your threads, they each end up with their own seperate copies of your sub f(), along with (almost) everything else in the interpreter.
As you can see, the purpose of :locked subroutine attribute is completely negated by the design of ithreads. The problem is that whilst it is possible at the system (C/OS) level to share code between threads and have seperate copies of data (ie. reentrent code), at the perl interpreter level, it is not. Perl (byte)"code" is simply another form of data at the system level, and is not reentrant. Hence, the ithreads design works around this by creating copies of the entire (system level) data segments which in perl terms means that all user-level code is also replicated. It's an unfortunate fact of life that perl long history means that adapting the current sources to allow true threading at the perl level is not viable, even on platforms that support threading natively. Re-writing the compiler and interpreter to segregate the perl code from the perl data such that perl code would become reentrant would be a nightmare to undertake. I think this may be one of the motivations behind Ponie, though that's a guess as I've yet to see it stated, and if it is, it is only one of many, Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller If I understand your problem, I can solve it! Of course, the same can be said for you. | [reply] [d/l] | ||||||
by Anonymous Monk on Sep 24, 2003 at 07:38 UTC | |||||||
Well, the purpose (as I understand it) is still valid, I'd say. You certainly want to be able to lock() manipulations of :shared (or shared()) variables. If this simply isn't possible in 5.8, well, bummer.
Indeed, threads::shared lock()s are BLOCK-based. Very convenient to name those blocks (as subs/methods), and synchronize their execution, automagically.
(Hmm -- maybe time to get an account, if just for this thread, er, ithreads :) | [reply] [d/l] | ||||||
by BrowserUk (Patriarch) on Sep 24, 2003 at 08:45 UTC | |||||||
The function of mutexing access to shared data hasn't gone away and this function is catered for in iThreads by the use of the :shared variable attribute or threads::shared::shared() function, in conjunction with the threads::shared::lock() function. The purpose of the :locked subroutine attribute is no longer valid, as it is impossible to share perl subroutines bewteen threads. What my example code attempted to demonstrate is that your attempt to use the :locked attribute to prevent two threads from concurrently executing your sub f(), served no purpose as, despite surface appearance, each thread was in fact getting it's own unique copy of that sub. So even if the locked attribute semaphore code is still operational under ithreads, it would never come into effect as there will be two mutexes applied to two pieces of data (presumable the subs cv entry in the symbol table) and the two entities could never interfere with each other directly. However, if the sub uses a shared variables (as in my $var : shared; or my $var; share( $var);), the the presence of the :locked attribute on the subroutine would not only serve no useful purpose, it might actually lull the unsuspecting into believing that they do not need to use the lock() function on the shared variables, which is inherently dangerous. I guess that the fact that the :locked subroutined attribute doesn't raise either a syntax or unknown attribute error under iThreads should be considered a bug! Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller If I understand your problem, I can solve it! Of course, the same can be said for you. | [reply] [d/l] [select] | ||||||
|
Re: (ithreads) :locked subs
by PodMaster (Abbot) on Sep 24, 2003 at 06:25 UTC | |||||||
lockedAnd that's basically what happens (i think you misunderstand what locking does).
| [reply] [d/l] | ||||||
by Anonymous Monk on Sep 24, 2003 at 07:13 UTC | |||||||
Let me rephrase -- I expected :locked subs to function like the docs indicate that the (not available under 5.8) manual lock()ing of a CODEREF (that is, lock(\&f)) used to function. That is, that invocations of ":locked" or ":locked :method" subs would be synchronized and thus serialized, rather like sync'd methods in Java.
By way of illustration, this is the moral equivalent of what I expected :locked to do:
Run it and you'll see that the threads are locking each other out. A useful device to prevent shared state corruption, very much like Java's "synchronized" keyword.
I'm having a hard time reading attributes.pm any other way. | [reply] [d/l] | ||||||
by PodMaster (Abbot) on Sep 24, 2003 at 07:41 UTC | |||||||
| [reply] | ||||||
|
Thread::Synchronize
by liz (Monsignor) on Sep 29, 2003 at 15:15 UTC | |||||||
Actually, this implementation uses a source filter, so no actual attribute handling is involved during runtime. Liz
Update: | [reply] | ||||||