Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl6 Thread reading interference

I need to have multiple threads each read from the same socket or from $*IN; however, there seems to be error because each is trying to read from the same source (I think). What is the best way to resolve this problem? Thanks !!

my $x = start { prompt("I am X: Enter x: "); }
my $y = start { prompt("I am Y: Enter y: "); }

await $x, $y;
say $x;
say $y;

And here are the errors:

I am X: Enter x: I am Y: Enter y: Tried to get the result of a broken Promise
  in block <unit> at zz.pl line 4

Original exception:
    Tried to read() from an IO handle outside its originating thread
      in block  at zz.pl line 1

Thanks !!

like image 314
lisprogtor Avatar asked Sep 03 '17 15:09

lisprogtor


1 Answers

On the latest development snapshot of Rakudo, your code actually works without throwing any exception on my system...
However, it still immediately asks for both values (I am X: Enter x: I am Y: Enter y:).

To make the second prompt wait until the first one has completed, you could use a Lock:

#--- Main code ---

my $x = start { synchronized-prompt "I am X: Enter x: "; }
my $y = start { synchronized-prompt "I am Y: Enter y: "; }

await $x, $y;
say $x.result;
say $y.result;


#--- Helper routines ---

BEGIN my $prompt-lock = Lock.new;

sub synchronized-prompt ($message) {
    $prompt-lock.protect: { prompt $message; }
}

The tricky part is that the lock needs to be initialized before the threads start using it concurrently. That's why I call Lock.new outside of the synchronized-prompt subroutine, in the mainline of the program. Instead of doing it at the top of the program, I use a BEGIN phaser so that I can place it next to the subroutine.

like image 55
smls Avatar answered Nov 15 '22 07:11

smls