8

Perl のドキュメントには次 のように書かれています。

以下のプログラムを使用ps -Lm <pid>すると、スレッドが並行して実行されていることがわかります。つまり、スレッドは異なるコアで同時に実行されています。しかし、4 つのスレッド (3 つとメイン) がある場合でも、ps auxPerl プロセスは 1 つしか表示されません。

  1. これは、各スレッドにPerl インタープリター全体があるということですか?
  2. Perl スレッドはシステム スレッドにマップされていますか?
  3. 2 が真の場合、1 つのプロセス内で複数の Perl インタープリターを使用するにはどうすればよいですか?
use threads;

$thr = threads->new(\&sub1);
$thr2 = threads->new(\&sub1);
$thr3 = threads->new(\&sub1);

sub sub1 { 
      $i = 0;
      while(true){
        $i = int(rand(10)) + $i;
      }
}


$thr->join;
4

2 に答える 2

13

「Perl インタープリター」とは、Perl コードが実行される環境を指します。ユーザーの観点から見ると、それはほとんどがシンボル テーブルとその中のグローバルですが、多数の内部変数 (たとえば、解析中に使用されるもの、現在の操作など) も含まれています。

  1. はい、スレッドごとに Perl インタープリターがあります。

  2. はい、Perl スレッドはシステム スレッドです。

  3. 「Perl インタープリター」は、任意の数のインスタンスを作成できるクラスと考えてください。* Perl では、これをMultiplicityと呼びます。アプリケーションに Perl インタープリターを組み込む方法については、perlembedを参照してください。


* — Perl をビルドするときに を使用する必要があります。これは、スレッド サポートが Perl に追加される方法である-Dusemulitplicityによって暗示されます。-Dusethreadsそれ以外の場合、「クラス」の代わりに一連のグローバルが使用されます。

于 2012-09-21T18:58:03.687 に答える
8

3 番目の質問に対する池上の回答を拡大するために、Perl は各オペレーティング システム スレッドのインタープリターの状態全体の完全なコピーを作成します。これは、すべてのデータとコードがコピーされることを意味します。マイナス面としては、これによりスレッドの作成が遅くなり、Perl スレッドはメモリを大量に消費します。

利点として、スレッドは互いに分離されているため、スレッドセーフなコードを簡単に記述できます。たとえば、ほとんどのモジュールは本質的にスレッドセーフであり、作成者が特別なことをしたり、スレッドについて考えたりする必要はまったくありません。

これは Perl の 2 番目のスレッド実装です。最初の 5.005 スレッドは、スレッドがコードとグローバル変数を共有する、より伝統的なスレッド モデルでした。うまくいきませんでした。さらに悪いことに、調整されていないグローバル変数がさまざまなスレッド間で互いに衝突したため、ほとんどの CPAN モジュールが役に立たなくなりました。

それがどうして可能なのかというと、池上さんが言って説明した「多重性」というものです。これはもともと、Perl インタープリターを別の C または C++ プログラムに組み込みたいという願望から生まれました。プロセスで実行されている唯一の Perl インタープリターを想定するのではなく、インタープリター オブジェクトごとにすべてのグローバル データ (グローバル変数とコンパイル済みコード) を分離するように、Perl の動作方法を変更する必要がありました。そこから、Perl インタープリター内の複数の Perl インタープリターがforkWindows 上でエミュレートするために使用されました。最後に、その大規模な作業の上に構築された 5.6 スレッド。

于 2012-09-21T20:52:20.400 に答える