1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#!/usr/bin/perl
# Threads testing code for possible use in Taktuk
# This is a producer-consumer tested in Perl 5.8.6
# Characteristics :
# - Despite what I've found in the Perl documentation, modern versions of Perl
# seem to share blessing among threads
# - Sharing do not dereference references, i.e. it is limited to flat structures
# (this explain why each new produced object has to be shared explicitely
use strict;
package container;
sub new()
{
my $data = {'data'=>3};
bless($data);
return($data);
}
sub set_data($)
{
my $self = shift;
$self->{'data'} = shift;
}
sub get_data()
{
my $self = shift;
return $self->{'data'};
}
package prodcons;
use threads;
use threads::shared;
sub new()
{
my $data = &share([]);
bless($data);
return($data);
}
sub prod($)
{
my $self = shift;
lock($self);
push @$self, shift;
cond_signal($self);
}
sub cons()
{
my $self = shift;
lock($self);
while (not scalar(@$self))
{
cond_wait($self);
}
return shift @$self;
}
package test;
use threads;
use threads::shared;
our $num_elements = 10;
our $num_threads = 10;
sub producer($)
{
my $prodcons = shift;
my $container;
my $self = threads->self;
for (my $i=0; $i<$num_elements; $i++)
{
print ($self->tid.": I will enqueue ".$i*$i."\n");
$container = container::new;
share($container);
$container->set_data($i*$i);
$prodcons->prod($container);
$self->yield;
}
}
sub consumer($)
{
my $prodcons = shift;
my $container;
my $self = threads->self;
for (my $i=0; $i<$num_elements; $i++)
{
$container = $prodcons->cons;
print ($self->tid.": I have dequeued ".$container->get_data."\n");
$self->yield;
}
}
my $prodcons = prodcons::new;
my @producers;
my @consumers;
for (my $i=0; $i<$num_threads; $i++)
{
push @consumers, threads->create("consumer",$prodcons);
}
for (my $i=0; $i<$num_threads; $i++)
{
push @producers, threads->create("producer",$prodcons);
}
while (scalar(@producers))
{
my $producer = shift @producers;
$producer->join;
}
while (scalar(@consumers))
{
my $consumer = shift @consumers;
$consumer->join;
}
print "End of program\n";
|