#!perl -w use strict; use threads; use Thread::Queue; use Data::Dumper; my $q_display = Thread::Queue->new(); my $display_control = threads->create( sub { while (my $info = $q_display->dequeue()) { #warn Dumper $info; my ($command, @data) = @$info; if ($command eq 'status') { print "Status: $_\n" for @data; } elsif ($command eq 'prompt') { my ($prompt, $id, $response_queue) = @data; print "$prompt\n"; my $response = <>; $response_queue->enqueue([$id, $response]); }; }; }); sub get_info { my ($prompt) = @_; my $response = Thread::Queue->new(); $prompt = "[thread " . threads->tid . " asks] $prompt"; my $request_id = threads->tid; $q_display->enqueue([prompt => $prompt, $request_id, $response]); my $res = $response->dequeue; my ($id,$val) = @$res; if ($id ne $request_id) { die "Internal error. Asked for $request_id, got $id"; }; $val }; sub send_status { my (@msg) = @_; $_ = "[thread " . threads->tid . " status] $_" for @msg; $q_display->enqueue([status => @msg]); }; sub hello_world { sleep rand 5; my $name = get_info( 'What is your name?' ); sleep rand 10; send_status("Hello $name") }; my @running = map { async \&hello_world; } 1..4; # Wait for all child threads to finish $_->join for @running; # Stop the display thread $q_display->enqueue(undef); $display_control->join; print "Done\n";