> > > You mean "is parallel" as a synonym for "is async"? > > > > I think "is parallel" denotes something as usable by multiple threads > > simultaneously, "in parallel". > > "is serial" would denote that only one thread can use the $thing at a > > time, exclusively. > > Are you saying both are asynchronous, but one specifies that a resource > should be locked rather than duplicated? > > > . . . > > > If $age has been passed to an asynchronous closure, it should be > > > marked as locked, and other threads trying to access it would have > > > to get a lock first. Yes, lots of overhead.... but that way if the > > > default is WAIT (which seems the smart default to me), the thread > > > waits until TakesForever() releases the resource. > > In that light, responding to my own comment, you could infer that you > should lock anything passed by reference, and not worry about it if > passed by value unless you said "$age is locked" or "is serial" or > whatever, yes?
Correct - since only references can affect their originator (or whatever you call it). Modifying something passed by value would be exempt. > > > > if we declare > > > > > > our method TakesForever ( int $num is serial ) is async but NOWAIT > > { > > > ... > > > } > > > > > > or > > > > > > my $age = 27 but NOWAIT; > > > > > > or > > > > > > TakesForever( $age but NOWAIT ); > > > > > > (or whatever) then I'd say it should just fail. I mean, isn't that > > kind > > > of the idea, to have that sort of flexibility? > > > > > > > Perhaps some more syntax-play is in order here. > > lol -- yeah. :) > > > One thing about threading with Perl5 is that it is easy to write a > > simple threaded program that is entirely opaque - unless you > > wrote the program yourself. > > > > The program below gets a list of coderefs and executes each one, then > > returns the result. > > #================================================ > > (Using the threads.pm way...) > > package QueueRunner; > > > > use strict; > > use threads; > > use threads::shared; > > > > sub process_job_queue > > { > > my ($s, @jobs_in) = @_; > > my @results : shared = (); > > my @workers = (); > > > > push @workers, async { push( @results, $_->() ) } foreach @jobs_in; > > $_->join foreach @workers; > > return @results; > > }# end process_job_queue() > > > > # Elsewhere... > > package main; > > > > my @answer = QueueRunner->process_job_queue( \&job1, \&job2, \&job3 > > ); > > > > #================================================ > > And my attempt at the same, using Perl6: > > #================================================ > > > > class QueueRunner { > > our sub process_job_queue( Code @jobs_in ) returns List of Any { > > my Any @results is parallel; > > my Thread @workers = (); > > > > for @jobs_in { > > @workers.push( async { &_() } ); > > } > > for @workers { > > @results.push( $_.join() ); > > } > > > > return @results; > > }# end process_job_queue() > > }# end QueueRunner > > > > # Elsewhere... > > my @answer = QueueRunner.process_job_queue( @jobs ); > > > > #================================================ > > > > I made absolutely no progress here. It seems to me that it's no more > > obvious what's going on here than in the Perl5 version. Any > > comments? > > > > Regards, > > John Drago > > Hm. If we're using *implicit* threads (which I thought was the point), > how about > > class QueueRunner { > > our sub process_queue(Code @jobs_in) { > my @ans is serial; > @ans.push map { async { &_() } } @jobs_in; > > @ans; > } > > }# end QueueRunner > > # Elsewhere... > my @answer = QueueRunner.process_job_queue( @jobs ); > > The point is that the call to async() is supposed to handle the thread > management for you, isn't it? > > Though if that works, you could squish this example even more, to > > class QueueRunner { > > our sub process_queue(Code @jobs_in) { > map { async { &_() } } @jobs_in; > } > > }# end QueueRunner > > # Elsewhere... > my @answer = QueueRunner.process_job_queue( @jobs ); > > and the issues of serialization are hidden in the map() call. For all > that.... > > my @answer = map { async { &_() } } @jobs; > > though that gets away from the point. > > Someone smack me if I'm drifting too far here? > Actually I think you did it just right. I think that horse is dead now. So, what about "serial" classes and methods?: # Does marking this class "is serial" mean it's forced to be a singleton? class Foo is serial { has $.counted = 0; our method Qux { say($.counted++ ~ " Foo.Qux"); } } # Only one thread may call Bar.Baz() at a time: class Bar { has $.counted = 0; our method Baz is serial { say($.counted++ ~ " Bar.Baz"); } } # ... later ... my Foo $foo = Foo.new(); my Bar $bar = Bar.new(); # $foo and $bar are implicitly shared with other threads: for 1..5 { async { is atomic; $foo.Qux(); $bar.Baz(); }; } ...what would it print? 1 Foo.Qux 1 Bar.Baz 2 Bar.Baz 2 Foo.Qux 3 Bar.Baz 4 Bar.Baz 3 Foo.Qux 5 Bar.Baz 6 Bar.Baz 4 Foo.Qux 7 Bar.Baz 8 Bar.Baz 5 Foo.Qux 9 Bar.Baz 10 Bar.Baz (Now the first thread would be done with $foo, so the second thread could use it.) 6 Foo.Qux 7 Foo.Qux 8 Foo.Qux 9 Foo.Qux 10 Foo.Qux ----------------------------------------------- Regards, John Drago