3

私はperlが初めてで、マルチスレッドを試しています。次のプログラムがすべてのスレッドを作成し、少なくとも5秒後に「すべてのスレッドを作成しました」と出力し、一度実行するとすべてのスレッドが入力値を待っていることを期待していました。

use threads;

my @arr = (1,2,3,4);
foreach (@arr) {
    sleep(1);
    print "\ncreating...\n";
    threads->new(\&echo, $_);
    print "\ncreated\n";
}
print "\ncreated all the threads\n";
sleep(200); #wait for the threads to finish

sub echo {
    my ($thread) = @_;
    print "\nthread($thread) Enter the value:\n";
    my $value = <>;
    print "\nthread($thread) Got value= $value\n";
}

しかし、私は次のアウトアウトを得ています:

creating...

created

thread(1) Enter the value:

creating...

他の 3 つのスレッドはまだ作成されていないようです。sleep(1) を削除すると、期待どおりの結果が得られることがありますが、sleep(1) を使用すると、数分待っても上記の結果が得られます。私が見逃している可能性があるものは何ですか?基本的なことだと思いますが、わかりません。

アップデート:

同じプログラムが Linux で問題なく動作しますが、Windows のプラットフォーム固有の問題は何でしょうか?

更新 2:

同じ行の次の Java プログラムは、同じボックスで問題なく動作します。

import java.io.IOException;


public class MT {

    public static void main(String[] args)throws Exception {
        for(int i=0;i<4;i++){
            Thread.sleep(2000);
            new Thread(new Task(i)).start();
        }
        System.out.println("created all the threads");
        Thread.sleep(20000);

    }

    static class Task implements Runnable{

        int i;
        public Task(int i) {
            super();
            this.i = i;
        }
        @Override
        public void run() {
            try {
                System.out.println("Thread:"+i+" Enter value");
                int x= System.in.read();
                System.out.println(x);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Windows で perl がどのようにマルチスレッドをサポートしているかわかりません!

4

1 に答える 1

2

実際には、2 つの異なるブロッキングの問題があります。

  1. コンソールでの I/O バッファリング (これを提案してくれた Disco 3 に感謝します)。
  2. 標準入力から読み取るスレッドは互いにブロックします (ただし、他のスレッドはブロックしません)。

次のテスト プログラムを検討してください。

use threads;
 $| = 1;

my $thr1 = threads->new(\&echo, 1);
my $thr2 = threads->new(\&print_dots, 2);
sleep 10;
my $thr3 = threads->new(\&echo, 3);

sleep 200;



sub print_dots {
    while (1) {
        print ".";
        sleep 1;
    }
}

sub echo {

    my ($thread) = @_;
    print "\nthread($thread) Enter the value:\n";
    sleep 1;
    my $value = <>;
    print "\nthread($thread) Got value= $value\n";
}

I/O バッファリングを無効にしない場合 (によって行われ$|=1;ます)、ドットはまったく表示されません。入力バッファリングを無効にすると、ドットを出力するスレッドがブロックされることはありません。ただし、コンソールから読み取る 2 番目のスレッドは、まだ最初のスレッドによってブロックされています。

Windows 上の Perl で標準入力から真のノンブロッキング読み取りが必要な場合、いくつかの解決策が考えられます。 Win32::Consoleおそらく開始するのに適した場所です。これは潜在的に役立つ議論です。

于 2012-10-16T14:12:57.963 に答える