> > > 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


Reply via email to