Changeset 20063 for docs/Perl6/Spec

Show
Ignore:
Timestamp:
03/05/08 00:04:41 (9 months ago)
Author:
buchetc
Message:

[Spec] start re-oraginze S17

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • docs/Perl6/Spec/Concurrency.pod

    r19851 r20063  
    33=head1 TITLE 
    44 
    5 Synopsis 17: Concurrency [DRAFT] 
     5DRAFT: Synopsis 17: Concurrency 
    66 
    77=head1 AUTHOR 
    88 
    9  Elizabeth Mattijsen <liz@dijkmat.nl> 
    10  Audrey Tang <audreyt@audreyt.org> 
     9Elizabeth Mattijsen <liz@dijkmat.nl> 
     10Audrey Tang <audreyt@audreyt.org> 
    1111 
    1212=head1 VERSION 
    1313 
    14  Maintainer: Elizabeth Mattijsen <liz@dijkmat.nl> 
    15  Date: 13 Jun 2005 
    16  Last Modified: 08 Feb 2008 
    17  Number: 0 
    18  Version: 2 
    19  
    20 =head1 SKETCH 
    21  
    22 This is a rough sketch of how concurrency works in Perl 6. 
    23  
    24 (actually these are just random notes, put here under the release-early 
    25 release-often principle, slowly being integrated in a more textual format. 
    26 Patches welcome!) 
    27  
    28 =head1 OVERVIEW 
     14 Maintainer:    Elizabeth Mattijsen <liz@dijkmat.nl> 
     15 Contributions: Christoph Buchetmann 
     16 Date:          13 Jun 2005 
     17 Last Modified: 4 Mar 2008 
     18 Number         0 
     19 Version:       3 
     20 
     21This is a draft document. After being some time under the surface of Perl 6 
     22development this is a attempt to document working concurrency issues, list the 
     23remaining todos and mark the probably obsolete and redundant points. 
     24 
     25=head1 Overview 
    2926 
    3027Concurrency can take many forms in Perl 6.  With varying degrees of 
     
    8380access inside a thread, except for those with an explicit "is shared" 
    8481attribute?) 
     82 
     83=head1 Contend/Maybe/Defer 
    8584 
    8685=head2 No user accessible locks 
     
    187186uninterruptability, you could use the "is critical" trait. 
    188187 
    189 =head2 Critical Code blocks 
     188=head3 Critical Code blocks 
    190189 
    191190 sub tricky is critical { 
     
    203202to restore the state to the beginning of the Code block. 
    204203 
    205 =head2 Mixing Atomic and Critical 
     204=head3 Mixing Atomic and Critical 
    206205 
    207206Both "atomic" as well as "critical" propagate down the call chain.  This means 
     
    217216of an Atomic Code block. 
    218217 
    219 =head2 Co-Routines 
    220  
    221  sub foo { 
    222     my @list = ( 1, 11, 17 ); 
    223     while (@list) { 
    224         @list.shift.produce; 
    225     } 
    226     return; 
    227  } 
    228  
    229  say foo; # 1 
    230  say foo; # 11 
    231  say foo; # 17 
    232  say foo; # undef 
    233  say foo; # 1 
     218 
     219=head1 Co-Routines 
    234220 
    235221There is no real difference between a subroutine (or method) and a so-called 
     
    259245the use of named parameters is therefore advisable. 
    260246 
    261 =head2 Threads 
    262  
    263  
    264 =head3 Kill all 
    265  
    266    CORE::GLOBAL::exit; # kills all the threads 
    267  
    268  
    269 =head3 Thread models  
     247=head2 Examples 
     248 
     249  coro dbl { yield $_ * 2; yield $_; }; 
     250  (1..4).map:{ dbl($_) } 
     251  # should result in 2 2 6 4 
     252 
     253 
     254 
     255=head1 Threads 
     256 
     257=head2 Thread methods and attributes 
    270258 
    271259We intentionally do not list cross-machine parallelism Conc:: classes here. 
     
    284272   Conc::Proc.this 
    285273 
    286 =head3 Thread methods and attributes 
    287  
    288 Conc object # name is still up for grabs! 
    289274 
    290275 - numify to TIDs (as in pugs) 
     
    335320 
    336321 
    337 =head3 Thread status 
    338  
    339 - IO objects and containers gets concurrency love! 
     322=head2 Thread status 
     323 
     324 -IO objects and containers gets concurrency love! 
    340325    - $obj.wake_on_readable 
    341326    - $obj.wake_on_writable 
     
    348333    async { @a.unshift({ ... }) }; 
    349334 
    350 Communication abstractions 
    351 - shared, transactional variables by default 
     335 Communication abstractions 
     336 - shared, transactional variables by default 
    352337 
    353338# program will wait for _all_ threads 
     
    355340# of the parent thread that spawned them 
    356341 
    357  
    358 =head2 Still more or less unorganized stuff 
    359  
    360  
    361 ### INTERFACE BARRIER ### 
    362 module Blah; 
    363 { 
    364  
    365     is atomic;   # contend/maybe/whatever other rollback stuff 
    366                  # limitation: no external IO (without lethal warnings anyway) 
    367                  # can't do anything irreversible 
    368  
    369     is critical; # free to do anything irreversible 
    370                  # means "don't interrupt me" 
    371                  # in system with critical section, no interrupts from 
    372                  # other threads will happen during execution 
    373                  # you can't suspend me 
    374  
    375     my $boo is export; 
    376     $boo = 1; 
    377  
    378     # We decree that this part forms the static interface 
    379     # it's run once during initial compilation under the 
    380     # Separate Compilation doctrine and the syms sealed off 
    381     # to form part of bytecode syms headers 
    382     %CALLER::<&blah> = { 1 }; # work - adds to export set 
    383     die "Eureka!" if %CALLER::<$sym>; # never dies 
    384  
    385     # BEGIN { $boo = time }; 
    386  
    387     sub IMPORT { 
    388         # VERY DYNAMIC! 
    389  
    390         our $i = time; 
    391         %CALLER::<&blah> = { 1 }; # work - adds to export set 
    392         die "Eureka!" if %CALLER::<$sym>; # probes interactively 
    393     } 
    394 } 
    395 ### INTERFACE BARRIER ### 
    396  
    397 my $sym; 
    398 threads.new({ 
    399     use Blah; 
    400     BEGIN { require(Blah).import } 
    401  
    402     my $boo; BEGIN { eval slurp<Blah.pm>; $boo := $Blah::boo }; 
    403  
    404     ... 
    405 }); 
    406342 
    407343=head2 Signals 
     
    484420=head2 Continuations 
    485421 
    486 =head3 Coroutines 
    487  
    488 ## braindump of coro meeting by Liz and Autri, more to follow 
     422=head2 Junctive Autothreading and Hyper Operations 
     423 
     424Live in userland for the time being. 
     425 
     426=head2 Interprocess Communication 
     427 
     428=head2 I/O Considerations 
     429 
     430=head3 File Descriptors 
     431 
     432=head3 Sockets 
     433 
     434 
     435=head2 Still more or less unorganized stuff 
     436 
     437 
     438### INTERFACE BARRIER ### 
     439module Blah; 
     440{ 
     441 
     442    is atomic;   # contend/maybe/whatever other rollback stuff 
     443                 # limitation: no external IO (without lethal warnings anyway) 
     444                 # can't do anything irreversible 
     445 
     446    is critical; # free to do anything irreversible 
     447                 # means "don't interrupt me" 
     448                 # in system with critical section, no interrupts from 
     449                 # other threads will happen during execution 
     450                 # you can't suspend me 
     451 
     452    my $boo is export; 
     453    $boo = 1; 
     454 
     455    # We decree that this part forms the static interface 
     456    # it's run once during initial compilation under the 
     457    # Separate Compilation doctrine and the syms sealed off 
     458    # to form part of bytecode syms headers 
     459    %CALLER::<&blah> = { 1 }; # work - adds to export set 
     460    die "Eureka!" if %CALLER::<$sym>; # never dies 
     461 
     462    # BEGIN { $boo = time }; 
     463 
     464    sub IMPORT { 
     465        # VERY DYNAMIC! 
     466 
     467        our $i = time; 
     468        %CALLER::<&blah> = { 1 }; # work - adds to export set 
     469        die "Eureka!" if %CALLER::<$sym>; # probes interactively 
     470    } 
     471} 
     472### INTERFACE BARRIER ### 
     473 
     474=head3 braindump of coro meeting by Liz and Autri, more to follow 
    489475 
    490476- Coros are _like_ processes 
    491477 
    492 coro dbl { yield $_ * 2; yield $_; return }; 
    493 my @x = 1..10; 
    494 my %y = map &dbl, @x; 
    495 # 2 => 2, 6 => 4, 10 => 6, ... 
    496  
    497 coro perm (@x) { 
    498     @x.splice(rand(@x),1).yield while @x; 
    499 } 
    500  
    501 my &p1 := &perm.start(1..10); 
    502 my &p2 := &perm.start(1..20); 
    503  
    504 p1(); p1(); 
    505 p2(); p2(); 
    506  
    507 coro foo { yield 42 }; 
    508  
    509 (1..10).pick; 
    510  
    511 coro foo ($x) { 
     478  coro perm (@x) { 
     479     @x.splice(rand(@x),1).yield while @x; 
     480  } 
     481  my &p1 := &perm.start(1..10); 
     482  my &p2 := &perm.start(1..20); 
     483  p1(); p1(); 
     484  p2(); p2(); 
     485 
     486  coro foo { yield 42 }; 
     487 
     488  coro foo ($x) { 
    512489    yield $x; 
    513490    yield $x+2; 
     
    518495        } 
    519496    } 
    520 } # implicit falloff return + return() means start over without yielding 
    521   # return() means yielding and restart + no implicit falloff (I LIKE THIS) 
    522  
    523 &foo.finished; # true on return() and false on midway yield() 
    524  
    525 foo(4); # and that's all she wrote 
    526  
    527 coro foo ($x) { 
     497  } # implicit falloff return + return() means start over without yielding 
     498    # return() means yielding and restart + no implicit falloff (I LIKE THIS) 
     499 
     500  &foo.finished; # true on return() and false on midway yield() 
     501 
     502  foo(4); # and that's all she wrote 
     503 
     504  coro foo ($x) { 
    528505    yield $x; 
    529506    # this point with $x bound to 10 
     
    531508    return 5; 
    532509    ... # this is never reached, I think we all agree 
    533 } 
    534  
    535 # If you don't want your variables to get rebound, use "is copy": 
    536 coro foo ($x is copy) {...} 
    537 # which is sugar for 
    538 coro foo ($x) { 
    539   { 
    540     my $x := $OUTER::x; 
    541     ...; 
    542     # Further calls of &foo rebound $OUTER::x, not $x. 
    543   } 
    544 } 
    545  
    546 sub foo { 
    547     return undef if rand; 
    548     ... 
    549 } 
    550  
    551 use overload { 
     510  } 
     511 
     512  # If you don't want your variables to get rebound, use "is copy": 
     513  coro foo ($x is copy) {...} 
     514  # which is sugar for 
     515  coro foo ($x) { 
     516    { 
     517      my $x := $OUTER::x; 
     518      ...; 
     519      # Further calls of &foo rebound $OUTER::x, not $x. 
     520    } 
     521  } 
     522 
     523  sub foo { 
     524     return undef if rand; 
     525     ... 
     526  } 
     527 
     528  use overload { 
    552529    '&{}' => sub { ... } 
    553 } 
    554  
    555 class Coro is Conc::Multiplex does Code { 
    556     method postcircumfix:<( )> { 
    557         # start the thread, block stuff (we are in the caller's context) 
    558     } 
    559 } 
    560  
    561 class Hash is extended { 
     530  } 
     531 
     532  class Coro is Conc::Multiplex does Code { 
     533     method postcircumfix:<( )> { 
     534         # start the thread, block stuff (we are in the caller's context) 
     535     } 
     536  } 
     537 
     538  class Hash is extended { 
    562539    method postcircumfix:<( )> (&self: *@_) { 
    563540        &self = self.start(@_); 
     
    567544        # upon return() or normal falloff, restore self 
    568545    } 
    569 } 
    570  
    571 %*ENV(123); 
    572  
    573 &foo_continued := &foo.start(10); 
    574 &foo.start(20); 
    575  
    576 foo(10);    # returns 10 
    577  
    578 foo();      # be "insufficient param" error or just return 11? 
    579 foo(20);    # returns 21 
    580  
    581 # continuation coros 
    582 multi foo () { ...no rebinding... } 
    583 multi foo ($x) { ...rebinding... } 
    584  
    585 &foo.kill; 
    586  
    587  
    588 my $first_ret = zoro( type => <even> ); 
    589 &zoro.variant(:type<even>).kill; 
    590 &zoro.variant(type => 'even').kill; 
    591  
    592 zoro( type => <odd> ); 
    593  
    594 zoro( even => 1 ); 
    595 zoro( odd => 1 ); 
    596  
    597 multi coro zoro ($type where 'even') {} 
    598 multi coro zoro ($type where 'odd') {} 
    599  
    600 multi coro zoro ($even is named) {} 
    601 multi coro zoro ($odd is named) {} 
    602  
    603  
    604 # iblech's thoughts: 
    605 # Coroutine parameters should never be rebound. Instead, yield(...)s return 
    606 # value is an Arglist object containing the new arguments: 
    607 coro bar ($a, $b) { 
     546  } 
     547 
     548  %*ENV(123); 
     549 
     550  &foo_continued := &foo.start(10); 
     551  &foo.start(20); 
     552 
     553  foo(10);    # returns 10 
     554 
     555  foo();      # be "insufficient param" error or just return 11? 
     556  foo(20);    # returns 21 
     557 
     558  # continuation coros 
     559  multi foo () { ...no rebinding... } 
     560  multi foo ($x) { ...rebinding... } 
     561 
     562  &foo.kill; 
     563 
     564 
     565  my $first_ret = zoro( type => <even> ); 
     566  &zoro.variant(:type<even>).kill; 
     567  &zoro.variant(type => 'even').kill; 
     568 
     569  zoro( type => <odd> ); 
     570 
     571  zoro( even => 1 ); 
     572  zoro( odd => 1 ); 
     573 
     574  multi coro zoro ($type where 'even') {} 
     575  multi coro zoro ($type where 'odd') {} 
     576 
     577  multi coro zoro ($even is named) {} 
     578  multi coro zoro ($odd is named) {} 
     579 
     580 
     581  # iblech's thoughts: 
     582  # Coroutine parameters should never be rebound. Instead, yield(...)s return 
     583  # value is an Arglist object containing the new arguments: 
     584  coro bar ($a, $b) { 
    608585    ...; 
    609586    my $new_set_of_args = yield(...); 
    610587    my $sum_of_old_a_and_new_a = $a + $new_set_of_args<$a>; 
    611588    ...; 
    612 } 
    613 bar(42, 23);  # $a is 42, $b is 23 
    614 bar(17, 19);  # $a still 42, $b still 19, 
    615               # $new_set_of_args is \(a => 17, b => 19) 
    616  
    617 =head2 Junctive Autothreading and Hyper Operations 
    618  
    619 Live in userland for the time being. 
    620  
    621 =head2 Interprocess Communication 
    622  
    623 =head2 I/O Considerations 
    624  
    625 =head3 File Descriptors 
    626  
    627 =head3 Sockets 
     589  } 
     590  bar(42, 23);  # $a is 42, $b is 23 
     591  bar(17, 19);  # $a still 42, $b still 19, 
    628592 
    629593=cut 
     594