Saturday, July 27, 2013

Illustrating Perl threads with simple Maths script

Why do we use threads? 
   One of the reason is to perform tasks in parallel and get better turn-around-time.
   Also a server program which accepts data from user's and assign the task to a thread. Once the task is assigned, server goes back to accept new requests.

Problem statement
Write a script which accepts 2 numbers from user and performs addition, subtraction, multiplication and division operations on it in parallel. The main scripts performs all the 4 arithmetic operations using threads and it returns back waiting for next input.

Sample invocation
   ./math2.pl
Output
Welcome to Slice Off Codes Math Calculator
Enter Number 1
89
Enter Number 2
37
soc_add thread started ...
soc_sub thread started ...
soc_mul thread started ...
soc_div thread started ...
Main thread ....
Press 1 to Continue
Press 2 to Quit
89 / 37 = 2.40540540540541
89 - 37 = 52
89 * 37 = 3293
89 + 37 = 126

Know-how: Threads
use threads;  #Perl thread module
#Creating threads
my $thr1 = threads->create(\&soc_add, $num1, $num2);
# Collecting return data from threads. It also waits for thread to exit
$my @return_data=$thr1->join();
#Don't wait for thread return, don't have return data, just detach
$thr1->detach();

Source code
Method 1: Using detach


#!/usr/bin/perl -w
use strict;
use Config;
use threads;

#Check to make sure this script is compiled on Perl with thread support enabled
$Config{useithreads} or die('Recompile Perl with threads to run this program.');

sub soc_add {
    my ($n1,$n2)=@_;
    print "soc_add thread started ...\n";
    sleep(5);
    my $sum=$n1+$n2;
    print "$n1 + $n2 = $sum \n";
}

sub soc_sub {
     my ($n1,$n2)=@_;
     print "soc_sub thread started ...\n";
     sleep(3);
     my $diff = $n1-$n2;
     print "$n1 - $n2 = $diff \n";
}

sub soc_mul {
     my ($n1,$n2)=@_;
     print "soc_mul thread started ...\n";
     sleep(4);
     my $prod = $n1*$n2;
     print "$n1 * $n2 = $prod \n";
}

sub soc_div {
     my ($n1,$n2)=@_;
     print "soc_div thread started ...\n";
     sleep(1);
     my $quot = $n1/$n2;
     print "$n1 / $n2 = $quot \n";
}

print "Welcome to Slice Off Codes Math Calculator\n";
while(1) {
    print "Enter Number 1\n";
    chomp(my $num1=<STDIN>);
    print "Enter Number 2\n";
    chomp(my $num2=<STDIN>);

    my $thr1 = threads->create(\&soc_add, $num1, $num2)->detach();
    my $thr2 = threads->create(\&soc_sub, $num1, $num2)->detach();
    my $thr3 = threads->create(\&soc_mul, $num1, $num2)->detach();
    my $thr4 = threads->create(\&soc_div, $num1, $num2)->detach();

    print "Main thread ....\n";
    print "Press 1 to Continue\n";
    print "Press 2 to Quit\n";
    chomp(my $status=<STDIN>);
    if ($status == 2 ) {
        exit(0);
    }
}

Method 2: Using join 
#!/usr/bin/perl -w
use strict;
use Config;
use threads;

#Check to make sure this script is compiled on Perl with thread support enabled
$Config{useithreads} or die('Recompile Perl with threads to run this program.');

sub soc_add {
    my ($n1,$n2)=@_;
    return($n1+$n2);
}

sub soc_sub {
     my ($n1,$n2)=@_;
     return($n1-$n2);
}

sub soc_mul {
     my ($n1,$n2)=@_;
     return($n1*$n2);
}

sub soc_div {
     my ($n1,$n2)=@_;
     return($n1/$n2);
}

print "Welcome to Slice Off Codes Math Calculator\n";
while(1) {
    print "Enter Number 1\n";
    chomp(my $num1=<STDIN>);
    print "Enter Number 2\n";
    chomp(my $num2=<STDIN>);

    my $thr1 = threads->create(\&soc_add, $num1, $num2);
    my $thr2 = threads->create(\&soc_sub, $num1, $num2);
    my $thr3 = threads->create(\&soc_mul, $num1, $num2);
    my $thr4 = threads->create(\&soc_div, $num1, $num2);
    my @sum=$thr1->join();
    my @diff=$thr2->join();
    my @prod=$thr3->join();
    my @quot=$thr4->join();

    print "$num1 + $num2 = $sum[0] \n";
    print "$num1 - $num2 = $diff[0] \n";
    print "$num1 * $num2 = $prod[0] \n";
    print "$num1 / $num2 = $quot[0] \n";

    print "Press 1 to Continue\n";
    print "Press 2 to Quit\n";
    chomp(my $status=<STDIN>);
    if ($status == 2 ) {
        exit(0);
    }

}

No comments:

Post a Comment