in reply to Re: Problem with using threads with modules.
in thread Problem with using threads with modules.
First of all, I want to thank you for you help :) I been struggling with this a while now.
When you say that I Implicitly shares objects across threads, how is this possible?
If I don't pass an object as an argument or uses an external global object in the thread, how can It share them. Are all objects that are in the same scope (i.e. sub routines, class) automatically shared without me using it. :\
To the program. I have included my original program an a working one that is not what I first had in mind and I don't know why it works, thats frightens me a bit ;).
Your code is close to want I wanted but it will not work in my case. The IO::Telnet-socket is the one who writes to $io so I cant access it because of the issue of sharing objects you told me. Instead the Update()-thread uses $var to update the screen and Telnet-socket output is connected to $io in the main thread.
With the small test program it was impossible to know how the program was composed so I have included my code and stripped all special features for easy reading.
This is how it is suppose to work. This class i called from another perl-module like run("192.168.0.1","23"). It uses Telnet to extract information from various devices and views it on screen and logs it on disc FileIO::save_log("traffic_log.txt",$var) by using $var as intermediate storage. IO::Telnet-socket is connected to $var through $sock->input_log($io).
The program is going to have several instances of run(...) working in parallell by using threads later on. Each instances has a thread Update() that updates screen with its traffic.
For all devices I going to have several program1()-subroutines. Because of all the instances of run(...)-threads I want as few class-variables as possible and declare them inside run(...)-subroutine.
This is how the original program looked like.
package CodeExecutor; use strict; use Net::Telnet; use threads; use threads::shared; #require "fileio.pl"; my $finished : shared=0; # Thread control var run("192.168.0.1","23"); sub run{ my $IP=shift; my $Port=shift; my $sock=getConnection($IP,$Port); # Get a telnet socket my $var:shared; # Traffic storage var require 'IO/String.pm'; my $io = IO::String->new($var); $sock->input_log($io); # Connect socketstream to $var my $th=threads->new(\&Update,\$var); # Start update thread program1($sock); # Run the program $th->join(); # Collect the thread if(defined $sock){ print "connection successful:".$sock; $sock->close(); } } sub program1{ my $sock=shift; eval{ print "Start"; $sock->waitfor('/Password:/'); $sock->print("cisco"); $sock->waitfor('/Router>/'); $sock->print("en"); $sock->waitfor('/Password:/'); $sock->print("cisco2"); $sock->waitfor('/Router#/'); sleep(2); $sock->print("show aliases"); $sock->waitfor('/Router#/'); $sock->print("show file systems"); $sock->waitfor('/Router#/'); }; if ($@){ print "Match Timeout"; } {lock $finished; $finished=1;} # Tells threads to stop #FileIO::save_log("traffic_log.txt",$var); # Save log to file } sub getConnection{ my $destIP=shift; my $destPort=shift; my $sock; eval{ $sock=new Net::Telnet(Host=>$destIP, Port=>$destPort, Timeout=>"20"); }; if ($@){ print "Could not get a connection"; exit(0); } return $sock; } # Update the screen with new Traffic # contained in $var sub Update{ my $var=shift; my $linenr=0; while(1){ my @bufflines=split(/\n/,$$var); # Print new lines only while($linenr<$#bufflines){ print $bufflines[$linenr++]."\n"; } {lock $finished; return if $finished;} sleep(1); # Update intervall } } 1; # Returning a true value
Now to the working one. The changes are:
package CodeExecutor; use strict; use Net::Telnet; use threads; use threads::shared; #require "fileio.pl"; my $finished : shared=0; # Thread control var my $var:shared; # Traffic storage var run("192.168.0.1","23"); sub run{ my $IP=shift; my $Port=shift; my $con=getConnection($IP,$Port); # Get a telnet socket my $th=threads->new(\&Update); # Start update thread program1($con); # Run the program $th->join(); # Collect the thread if(defined $con){ print "connection successful:".$con; $con->close(); } } sub program1{ my $sock=shift; require 'IO/String.pm'; my $io = IO::String->new($var); $sock->input_log($io); # Connect socketstream to $var eval{ print "Start"; $sock->waitfor('/Password:/'); $sock->print("cisco"); $sock->waitfor('/Router>/'); $sock->print("en"); $sock->waitfor('/Password:/'); $sock->print("cisco2"); $sock->waitfor('/Router#/'); sleep(2); $sock->print("show aliases"); $sock->waitfor('/Router#/'); $sock->print("show file systems"); $sock->waitfor('/Router#/'); }; if ($@){ print "Match Timeout"; } {lock $finished; $finished=1;} # Tells threads to stop #FileIO::save_log("traffic_log.txt",$var); # Save log to file } sub getConnection{ my $destIP=shift; my $destPort=shift; my $con; eval{ $con=new Net::Telnet(Host=>$destIP, Port=>$destPort, Timeout=>"20"); }; if ($@){ print "Could not get a connection"; exit(0); } return $con; } # Update the screen with new Traffic # contained in $var sub Update{ #my $var=shift; my $linenr=0; while(1){ my @bufflines=split(/\n/,$var); while($linenr<$#bufflines){ print $bufflines[$linenr++]."\n"; } {lock $finished; return if $finished;} sleep(1); } } 1; # Returning a true value
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Problem with using threads with modules.
by BrowserUk (Patriarch) on Jun 23, 2004 at 00:19 UTC | |
by tele2mag (Initiate) on Jun 23, 2004 at 19:02 UTC | |
by BrowserUk (Patriarch) on Jun 23, 2004 at 20:45 UTC | |
|
Re^3: Problem with using threads with modules.
by BrowserUk (Patriarch) on Jun 23, 2004 at 03:34 UTC | |
by tele2mag (Initiate) on Jun 23, 2004 at 21:41 UTC | |
by BrowserUk (Patriarch) on Jun 24, 2004 at 08:08 UTC | |
by tele2mag (Initiate) on Jun 28, 2004 at 14:27 UTC | |
by BrowserUk (Patriarch) on Jun 29, 2004 at 02:18 UTC | |
|