#!/usr/bin/perl use strict; use threads; use threads::shared; use Thread::Queue; sub fun1 { my (@str)=@_; print "it is in fun1: @str/n"; } sub fun2 { my $str=shift; print "it is in fun2: $str/n"; } sub fun3 { my $str=shift; print "it is in fun3: $str/n"; } sub fun4 { my ($str1, $str2) = (shift, shift); print "it is in fun4: $str1, $str2/n"; } my $safe_q = Thread::Queue->new(); my @funs = ("fun1", "fun2", "fun3", "fun4"); my %closure = ( "func" => undef, "args" => (), ); my $th2 = threads->new(/&producer, 4, %closure); my $th1 = threads->new(/&consumer, 4); $th1->join(); $th2->join(); sub consumer{ my $count = shift; my $tid; my $i = 0; my ($index, $closure); while ($i++ < $count) { next unless($closure = $safe_q->dequeue()); my $func_name = ${$closure}{'func'}; my @args = @{${$closure}{'args'}}; $tid = threads->new(/&$func_name, @args); $tid->join(); threads->yield(); } } sub producer{ my ($count) = (shift); my $i = 0; my ($entry, $index); while($i++ < $count) { $closure{"args"} = (); $index = int rand 4; print "$funs[$index] enque/n"; $closure{"func"} = $funs[$index]; push @{$closure{"args"}}, "haha"; push @{$closure{"args"}}, $funs[$index]; $safe_q->enqueue(/%closure); threads->yield(); } }