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:

  1. The IO::String is moved to the program1() because with it in run(...) (with the thread creation) caused my warnings.
  2. As an effect I have to move $var out of run(...) to be a class variable
  3. Update can now read $var directly without passing as argument
Here is the working code:
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
This code works but is not so good if I want to create multiple threads of this class. On the otherhand, maybe I am not doing it the right way... As usual, all inputs are highly appreciated.
Thanks again for the help! ;)


In reply to Re^2: Problem with using threads with modules. by tele2mag
in thread Problem with using threads with modules. by tele2mag

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.