Perl get value of variable from while(1) loop when sub() change it

468 views Asked by At

I got a small problem.

When I create thread in main block of script, which should get the $txt value in while(1) loop, in the same time program create TopLevel window and there is a Text() object in $txt string.

I want to read values from Text() object, only when Text() object will be created, but not earlier.

In my example $txt should be a global variable, but my thread read $txt variable only by 'undef'.

Is it possible to read variable from while(1) loop, when other subroutines change it?

I must watch $txt var in thread, because when i try start thread in makeTop(), Tk gives me error about non-exist string.

Thanks for advices.

CODE:

use Tk;
use threads;
use warnings;

$mw = new MainWindow;
our $txt = undef;

my $lab = $mw->Label( -text=>"Main window.", -font => "ansi 12 bold")->pack;
my $but = $mw->Button( -text=>"Create Toplevel", -command => \&makeTop)->pack;

my $thr = threads->create('urls_couter');

MainLoop;

sub urls_couter {
   while (1) {
        if (defined $txt){
          $txt->get('1.0','end');
        }
   }
}

sub makeTop {
   my $top = $mw->Toplevel(); 

   $fr = $top->Frame()->grid( -row => 1, -column => 1 );
   $fr2 = $top->Frame()->grid( -row => 2, -column => 1 );

   my $top_lab = $fr->Label( -text => "URLs (each on a separate line) : ",
                             -font => "ansi 12 bold")->pack;

   $txt = $fr->Text( -width => 44, -height => 20)->pack;
   $txt->insert('end', "xxxxxxx");

   my $but_close = 
          $fr2->Button(
               -text    => "Ready!", 
               -command => sub { my @urls = split("\n", $txt->get('1.0','end-1c')); }, 
               -relief  => "raised", 
               -font    => "ansi 12 bold")->grid( -padx => 100, -row => 1, -column => 1 );

   $fr2->Button( 
                -text    => "Close", 
                -command => sub { destroy $top; },
                -relief  => "raised",
                -font    => "ansi 12 bold")->grid( -pady => 10, -row => 1, -column => 2 );
}
1

There are 1 answers

0
xaxxon On

According to this

As just mentioned, all variables are, by default, thread local. To use shared variables, you need to also load threads::shared:

thread local means you won't see changes outside your thread, so after you create your thread, each thread (logically) has it's own copy of all the variables.