1

小さな問題が発生しました。

while(1) ループで $txt 値を取得する必要があるスクリプトのメイン ブロックでスレッドを作成すると、同時にプログラムで TopLevel ウィンドウが作成され、$txt 文字列に Text() オブジェクトが存在します。

Text() オブジェクトが作成されるときにのみ、 Text() オブジェクトから値を読み取りたいのですが、それ以前ではありません。

私の例では、$txt はグローバル変数である必要がありますが、私のスレッドは 'undef' によってのみ $txt 変数を読み取ります。

他のサブルーチンが変数を変更したときに、while(1) ループから変数を読み取ることは可能ですか?

makeTop() でスレッドを開始しようとすると、Tk が存在しない文字列に関するエラーを表示するため、スレッドで $txt 変数を監視する必要があります。

アドバイスをありがとう。

コード:

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 );
}
4

1 に答える 1

0

これによると

前述のように、すべての変数はデフォルトでスレッド ローカルです。共有変数を使用するには、threads::shared もロードする必要があります。

スレッド ローカルとは、スレッドの外部で変更が表示されないことを意味します。したがって、スレッドを作成した後、各スレッドは (論理的に) すべての変数の独自のコピーを持ちます。

于 2013-08-09T00:19:23.807 に答える