NAME

threads - Perl のインタプリタベースのスレッド

VERSION

この文書は threads バージョン 1.67 を記述しています。

SYNOPSIS

    use threads ('yield',
                 'stack_size' => 64*4096,
                 'exit' => 'threads_only',
                 'stringify');

    sub start_thread {
        my @args = @_;
        print('Thread started: ', join(' ', @args), "\n");
    }
    my $thr = threads->create('start_thread', 'argument');
    $thr->join();

    threads->create(sub { print("I am a thread\n"); })->join();

    my $thr2 = async { foreach (@files) { ... } };
    $thr2->join();
    if (my $err = $thr2->error()) {
        warn("Thread error: $err\n");
    }

    # Invoke thread in list context (implicit) so it can return a list
    my ($thr) = threads->create(sub { return (qw/a b c/); });
    # or specify list context explicitly
    my $thr = threads->create({'context' => 'list'},
                              sub { return (qw/a b c/); });
    my @results = $thr->join();

    $thr->detach();

    # Get a thread's object
    $thr = threads->self();
    $thr = threads->object($tid);

    # Get a thread's ID
    $tid = threads->tid();
    $tid = $thr->tid();
    $tid = "$thr";

    # Give other threads a chance to run
    threads->yield();
    yield();

    # Lists of non-detached threads
    my @threads = threads->list();
    my $thread_count = threads->list();

    my @running = threads->list(threads::running);
    my @joinable = threads->list(threads::joinable);

    # Test thread objects
    if ($thr1 == $thr2) {
        ...
    }

    # Manage thread stack size
    $stack_size = threads->get_stack_size();
    $old_size = threads->set_stack_size(32*4096);

    # Create a thread with a specific context and stack size
    my $thr = threads->create({ 'context'    => 'list',
                                'stack_size' => 32*4096,
                                'exit'       => 'thread_only' },
                              \&foo);

    # Get thread's context
    my $wantarray = $thr->wantarray();

    # Check thread's state
    if ($thr->is_running()) {
        sleep(1);
    }
    if ($thr->is_joinable()) {
        $thr->join();
    }

    # Send a signal to a thread
    $thr->kill('SIGUSR1');

    # Exit a thread
    threads->exit();

DESCRIPTION

Perl 5.6 はインタプリタスレッドと呼ばれるものを導入しました。 インタプリタスレッドは、スレッド毎に新たに Perl インタプリタを 生成することによって、また、デフォルトではいかなるデータや状態も スレッド間で共有しないことによって、5005スレッド (Perl 5.005 におけるスレッドモデル)とは区別されます。

Perl 5.8 より前では、これは Perl を組み込むする人々にとってのみ、 そして Windows で fork() をエミュレートするためにのみ利用可能でした。

threads API は、古い Thread.pm API におおまかに基づいています。 変数はスレッド間で共有されず、全ての変数はデフォルトで スレッドローカルなものであることに注意しておくことが非常に重要です。 共有変数を利用するには、threads::shared を使わなければなりません。

    use threads;
    use threads::shared;

また、スクリプト内ではできるだけ早いうちに use threads して スレッドを利用可能にしておくべきだし、 eval "", do, require, use の内部では スレッド操作ができないことに注意してください。 特に threads::shared を使って変数を共有しようとするならば、 use threads::shared の前に use threads しなければなりません。 (逆にしてしまうと threads は警告を発します。)

$thr = threads->create(FUNCTION, ARGS)

これは指定されたエントリポイント関数の実行を開始し、引数として ARGS リストが与えられる新しいスレッドを作ります。 対応するスレッドオブジェクトか、スレッド作成に失敗した場合は undef を返します。

FUNCTION は関数名、無名サブルーチン、コードリファレンスのいずれかです。

    my $thr = threads->create('func_name', ...);
        # or
    my $thr = threads->create(sub { ... }, ...);
        # or
    my $thr = threads->create(\&func, ...);

->new() メソッドは ->create() のエイリアスです。

$thr->join()

対応するスレッドが実行を終了するのを待ちます。 そのスレッドが終了した時、->join() は エントリポイント関数の戻り値を返します。

->join() のコンテキスト (無効、スカラ、リストのいずれか) は、 スレッド生成時に決定されます。

    # Create thread in list context (implicit)
    my ($thr1) = threads->create(sub {
                                    my @results = qw(a b c);
                                    return (@results);
                                 });
    #   or (explicit)
    my $thr1 = threads->create({'context' => 'list'},
                               sub {
                                    my @results = qw(a b c);
                                    return (@results);
                               });
    # Retrieve list results from thread
    my @res1 = $thr1->join();

    # Create thread in scalar context (implicit)
    my $thr2 = threads->create(sub {
                                    my $result = 42;
                                    return ($result);
                                 });
    # Retrieve scalar result from thread
    my $res2 = $thr2->join();

    # Create a thread in void context (explicit)
    my $thr3 = threads->create({'void' => 1},
                               sub { print("Hello, world\n"); });
    # Join the thread in void context (i.e., no return value)
    $thr3->join();

さらなる詳細については "THREAD CONTEXT" を参照してください。

全てのスレッドが join されるか detach される前にプログラムが終了した場合、 警告が発生します。

既に join しているスレッドに対して ->join()->detach() を 行うと、エラーが発生します。

$thr->detach()

スレッドを join 不可能にし、最終的な返り値を捨てるようにします。 プログラムが終了するとき、まだ実行中の detach されたスレッドは暗黙に 終了します。

全てのスレッドが join されるか detach される前にプログラムが終了した場合、 警告が発生します。

既に detach されたスレッドに ->join()->detach() を 呼び出すと、エラーが発生します。

threads->detach()

スレッドが自分自身を detach するためのクラスメソッドです。

threads->self()

スレッドが自身の threads オブジェクトを取得するためのクラスメソッドです。

$thr->tid()

スレッドの ID を返します。 スレッド ID はユニークな整数であり、プログラムの始まりとなる メインスレッドの値は 0 で、 新しいスレッドが生成されるたびに値を 1 増やしていきます。

threads->tid()

スレッドが自身の ID を得るためのクラスメソッドです。

"$thr"

use threads 宣言に stringify インポートオプションを追加すると、 文字列や文字列コンテキスト (例えばハッシュのキーとして) で スレッドオブジェクトを使おうとすると、その ID が値として使われます:

    use threads qw(stringify);

    my $thr = threads->create(...);
    print("Thread $thr started...\n");  # Prints out: Thread 1 started...
threads->object($tid)

指定されたスレッドに関連するアクティブな threads オブジェクトを返します。 もし TID で指定されたスレッドがない場合、join や detach されている場合、 TID が指定されていない場合、指定された TID が undef の 場合、メソッドは undef を返します。

threads->yield()

このスレッドが他のスレッドに CPU 時間を譲ってもいいということを OS に 示唆します。 実際に起こることは、基になっているスレッド実装に大きく依存しています。

コード内では、use threads qw(yield) してから、単に yield() を 使えます。

threads->list()
threads->list(threads::all)
threads->list(threads::running)
threads->list(threads::joinable)

引数なしで (または threads::all を使って) リストコンテキストの場合、 join されておらず、detach されていない全ての threads オブジェクトの リストを返します。 スカラコンテキストでは、上述のものの数を返します。

引数が の (または threads::running を使った) 場合、 join されておらず、detach されていない、まだ実行中の threads オブジェクトのリストを返します。

引数が の (または threads::joinable を使った) 場合、 join されておらず、detach されていない、実行が終了した (つまり ->join()ブロック されない) threads オブジェクトの リストを返します。

$thr1->equal($thr2)

2 つのスレッドオブジェクトが同じスレッドかどうかをテストします。 これはより自然な形にオーバーロードされます:

    if ($thr1 == $thr2) {
        print("Threads are the same\n");
    }
    # or
    if ($thr1 != $thr2) {
        print("Threads differ\n");
    }

(スレッドの比較はスレッド ID を基にします。)

async BLOCK;

async はその直後に続くブロックを実行するスレッドを生成します。 このブロックは無名サブルーチンとして扱われるので、閉じ大括弧の後に セミコロンをつけなければなりません。 threads->create() 同様、asyncthreads オブジェクトを返します。

$thr->error()

スレッドは 無効 コンテキストで実行されます。 このメソッドは、スレッドが 普通に 終了した場合は undef を返します。 さもなければ、スレッドの実行状態に関連づけられた $@ の値を 無効 コンテキストで返します。

$thr->_handle()

この プライベート メソッドは、スレッドオブジェクトに関連づけられた 内部スレッド構造体のメモリ位置を返します。 Win32 では、これは CreateThread から返される HANDLE 値へのポインタ (つまり HANDLE *) です; その他のプラットフォームでは、 pthread_create 呼び出しで使われる pthread_t 構造体へのポインタ (つまり pthread_t *) です。

このメソッドは、一般的な Perl スレッドプログラミングには無用です。 このメソッドの目的は、その他の (XS ベースの) スレッドモジュールが、 Perl スレッドと関連づけられている基礎となるスレッド構造体へのアクセスおよび おそらくは操作を可能にすることです。

threads->_handle()

スレッドが自身の handle を得るためのクラスメソッドです。

スレッドの終了

スレッドを終了するための通常の手法は、エントリポイント関数で 適切な返り値と共に return() を使うことです。

threads->exit()

もし必要なら、スレッドはいつでも threads->exit() を 呼び出すことで終了させることが出来ます。 これにより、スレッドはスカラコンテキストでは undef を返し、 リストコンテキストでは空リストを返します。

main スレッドから呼び出されると、exit(0) と同様に振る舞います。

threads->exit(status)

スレッドから呼び出されると、threads->exit() と同様に振る舞います (つまり、status 終了コードは無視されます)。

main スレッドから呼び出されると、exit(status) と同様に振る舞います。

die()

スレッドでの die() の呼び出しは、スレッドの異常終了を意味します。 まずスレッドでの $SIG{__DIE__} ハンドラが呼び出され、 それからスレッドは die() 呼び出しに渡された引数による警告メッセージと 共に終了します。

exit(status)

スレッドの内部で exit() を呼び出すと、 アプリケーション全体が終了します。 これのことにより、スレッドコード内部や、スレッド化された アプリケーションで使われるかも知れないモジュールでの exit() の使用は 強く非推奨です。

もし本当に exit() が必要なら、以下を使うことを考えてください:

    threads->exit() if threads->can('exit');   # Thread friendly
    exit(status);
use threads 'exit' => 'threads_only'

これはスレッド内での exit() 呼び出しのデフォルトの振る舞いをグローバルに 上書きし、事実上このような呼び出しを threads->exit() と同じ 振る舞いにします。 言い換えると、この設定によって、exit() を呼び出したときにスレッドだけを 終了させます。

これはグローバルな効果を持つので、この設定はモジュールのようなものの内部では 使うべきではありません。

main スレッドはこの設定の影響を受けません。

threads->create({'exit' => 'thread_only'}, ...)

これは新しく作られたスレッドの内側でだけ exit() のデフォルトの 振る舞いを上書きします。

$thr->set_thread_exit_only(boolean)

これは、スレッドの スレッドだけ終了 の振る舞いを、スレッドが作られた 後で変更するために使われます。 の値を渡すと、exit() によってスレッドだけが終了します。 の値を渡すと、exit() によってアプリケーションが終了します。

main スレッドはこの呼び出しの影響を受けません。

threads->set_thread_exit_only(boolean)

exit() の振る舞いを変えるためにスレッドの内側で使うための クラスメソッドです。

main スレッドはこの呼び出しの影響を受けません。

スレッドの状態

以下の真偽値メソッドはスレッドの 状態 を決定するのに便利です。

$thr->is_running()

スレッドがまだ実行されている(つまり、そのエントリポイント関数がまだ完了または 終了していない)なら真を返します。

$thr->is_joinable()

スレッドが実行を完了していて、detach も join もされていないなら真を返します。 言い換えると、このスレッドは join する準備が出来ていて、 $thr->join() の呼び出しは ブロック されません。

$thr->is_detached()

スレッドが detach されたなら真を返します。

threads->is_detached()

スレッドが detach されているかどうかを決定できるようにするための クラスメソッドです。

スレッドのコンテキスト

サブルーチンと同様、スレッドのエントリポイント関数から返される値の型は スレッドの コンテキスト (リスト、スカラ、無効のいずれか) によって 決定されます。 スレッドのコンテキストはスレッド作成時に決定されます。 これは、コンテキストをエントリポイント関数から wantarray() を使って利用可能にするために必要です。 それからスレッドは ->join() から返される適切な型の値を指定します。

明示的なコンテキスト

スレッドの作成とスレッドの join は異なったコンテキストで 行われるかもしれないので、スレッドのエントリポイント関数で明示的に コンテキストを宣言することが望ましいです。 これは最初の引数としてハッシュリファレンスを指定した ->create() を 呼び出すことで行えます:

    my $thr = threads->create({'context' => 'list'}, \&foo);
    ...
    my @results = $thr->join();

上述の場合、スレッドオブジェクトは親スレッドにスカラコンテキストで 返され、スレッドのエントリポイント関数 foo はリスト(配列)コンテキストで 予備されるので、親スレッドは ->join() 呼び出しからリスト(配列)を 受け取ります。 ('array''list' の同義語です。)

同様に、もしスレッドオブジェクトが必要だけれども、スレッドが値を返さない (つまり 無効 コンテキスト) 場合、以下のようにします:

    my $thr = threads->create({'context' => 'void'}, \&foo);
    ...
    $thr->join();

コンテキスト型はまた、ハッシュリファレンスの キー に引き続いて の 値としても使えます:

    threads->create({'scalar' => 1}, \&foo);
    ...
    my ($thr) = threads->list();
    my $result = $thr->join();

暗黙のコンテキスト

明示的に宣言されない場合、スレッドのコンテキストは ->create() 呼び出しのコンテキストになります:

    # Create thread in list context
    my ($thr) = threads->create(...);

    # Create thread in scalar context
    my $thr = threads->create(...);

    # Create thread in void context
    threads->create(...);

$thr->wantarray()

これは wantarray() と同じ方法でスレッドの コンテキストを返します。

threads->wantarray()

現在のスレッドのコンテキストを返すクラスメソッドです。 現在のスレッドのエントリポイント関数の内側で wantarray() を実行するのと同じ値を返します。

スレッドのスタックサイズ

デフォルトのスレッド毎のスタックサイズはプラットフォームによって大きく異なり、 ほとんど常にほとんどのアプリケーションが必要な量よりはるかに多いです。 Win32 では、Perl の makefile は明示的にデフォルトのスタックを 16 MB に 指定しています; その他のほとんどのシステムでは、システムのデフォルトが 使われますが、やはり必要な量よりはるかに多いです。

スタックサイズをアプリケーションのニーズにより正確に反映させることにより、 アプリケーションのメモリ使用量を著しく減少させ、同時実行スレッド数を 増やすことができるかもしれません。

従って、アドレス空間配置の粒度が 64 KB である Windows では、Win32 Perl で これより小さい値にスタックを設定してもメモリを節約できないことに 注意してください。

threads->get_stack_size();

現在のデフォルトのスレッド毎のスタックサイズを返します。 デフォルトは 0 で、これはシステムのデフォルトスタックサイズを 使っていることを示します。

$size = $thr->get_stack_size();

特定のスレッドのスタックサイズを返します。 返り値 0 は、そのスレッドでシステムデフォルトのスタックサイズが 使われていることを示します。

$old_size = threads->set_stack_size($new_size);

新しいデフォルトのスレッド毎のスタックサイズを設定し、以前の設定を 返します。

最小スレッドスタックサイズがあるプラットフォームもあります。 その値よりスタックサイズを小さくしようとすると警告が出て、最小 スタックサイズが使われます。

最大スタックサイズのある Linux プラットフォームもあります。 大きすぎるスタックサイズを設定するとスレッド作成に失敗します。

必要なら、$new_size は次のメモリページサイズ(普通は4096 か 8192)倍数に 切り上げられます。

スタックサイズが設定された後に作られたスレッドは pthread_attr_setstacksize() を呼び出す (pthreads プラットフォームの 場合)CreateThread() にスタックサイズを渡します (Win32 Perl の場合)

(明らかに、この呼び出しは既に存在するスレッドには影響を与えません。)

use threads ('stack_size' => VALUE);

これはアプリケーションの開始時にスタック単位のデフォルトのスタックサイズを 設定します。

$ENV{'PERL5_ITHREADS_STACK_SIZE'}

デフォルトのスレッド毎のスタックサイズは環境変数 PERL5_ITHREADS_STACK_SIZE を使ってアプリケーションの開始時に設定できます:

    PERL5_ITHREADS_STACK_SIZE=1048576
    export PERL5_ITHREADS_STACK_SIZE
    perl -e'use threads; print(threads->get_stack_size(), "\n")'

この値は use threads に与えられる stack_size 引数で上書きできます。 主な目的はレガシーなスレッドアプリケーションでスレッド毎のスタックサイズを 設定できるようにすることです。

threads->create({'stack_size' => VALUE}, FUNCTION, ARGS)

個々のスレッドの個別のスタックサイズを指定するには、最初の引数として ハッシュリファレンスを指定して ->create() を呼び出します:

    my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
$thr2 = $thr1->create(FUNCTION, ARGS)

これは既に存在するスレッド ($thr1) からスタックサイズを継承して新しい スレッド ($thr2) を作成します。 これは以下のものの短縮形です:

    my $stack_size = $thr1->get_stack_size();
    my $thr2 = threads->create({'stack_size' => $stack_size}, FUNCTION, ARGS);

スレッドとシグナル

安全なシグナルが有効なとき (デフォルトの振る舞いです - さらなる 詳細については "Unsafe signals" を参照してください)、シグナルは それぞれのスレッドに対して送られて動作します。

$thr->kill('SIG...');

指定されたシグナルをスレッドに送ります。 シグナル名と(正の)シグナル番号は kill() で 対応しているものと同じです。 例えば、'SIGTERM', 'TERM' と (OS に依存しますが) 15 は全て ->kill() への妥当な引数です。

メソッドチェーンができるように、スレッドオブジェクトを返します:

    $thr->kill('SIG...')->join();

シグナルハンドラは対応することを想定しているシグナルに対してスレッドで 設定される必要があります。 以下はスレッドを キャンセルする 例です:

    use threads;

    sub thr_func
    {
        # Thread 'cancellation' signal handler
        $SIG{'KILL'} = sub { threads->exit(); };

        ...
    }

    # Create a thread
    my $thr = threads->create('thr_func');

    ...

    # Signal the thread to terminate, and then detach
    # it so that it will get cleaned up automatically
    $thr->kill('KILL')->detach();

以下は基本的な 中断再開 の機能を提供するためにスレッドの シグナルをセマフォと組み合わせた使い方を示すための単純化されたもう一つの 例です:

    use threads;
    use Thread::Semaphore;

    sub thr_func
    {
        my $sema = shift;

        # Thread 'suspend/resume' signal handler
        $SIG{'STOP'} = sub {
            $sema->down();      # Thread suspended
            $sema->up();        # Thread resumes
        };

        ...
    }

    # Create a semaphore and pass it to a thread
    my $sema = Thread::Semaphore->new();
    my $thr = threads->create('thr_func', $sema);

    # Suspend the thread
    $sema->down();
    $thr->kill('STOP');

    ...

    # Allow the thread to continue
    $sema->up();

警告: このモジュールによって提供されているスレッドへのシグナル機能は 実際には OS 経由でシグナルを送っていません。 シグナルハンドラが適切なスレッドで呼び出されるように Perl レベルでシグナルを エミュレート しています。 例えば、$thr->kill('STOP') は実際にはスレッド(またはプロセス全体)を 停止させませんが、(上述したように) 対象のスレッドの $SIG{'STOP'} ハンドラが呼び出されます。

そのため、普通は kill() コマンドでの使用が適切ではないようなシグナル (例えば kill('KILL', $$))) は ->kill() メソッドで使っても (再び上述したように)問題ありません。

同様に、スレッドにシグナルを送ってもスレッドが今処理している操作を 妨害しません: シグナルは現在の処理が終了した後に処理されます。 例えば、スレッドが I/O 呼び出して 固まっている なら、シグナルが直ちに 処理されるように I/O 呼び出しを中断はしません。

終了したスレッドへのシグナル送信は無視されます。

警告

Perl exited with active threads:

全てのスレッドが join されるか detach される前にプログラムが終了した場合、 この警告が発生します。

注意: main スレッドが存在しているなら、後に示唆しているようにこの警告は no warnings 'threads'; を使って抑制できません。

Thread creation failed: pthread_create returned #

失敗の実際の原因を決定するには pthread_create の適切な man ページを 参照してください。

Thread # terminated abnormally: ...

スレッドが単にエントリポイント関数から返ったか threads->exit() を 使った以外の何らかの方法で終了しました。 例えば、エラーや die の使用によってスレッドが終了しました。

Using minimum thread stack size of #

最低スレッドスタックサイズがあるプラットフォームもあります。 スタックサイズをその値以下に設定しようとするとこの警告が出て、 スタックサイズは最小値に設定されます。

Thread creation failed: pthread_attr_setstacksize(SIZE) returned 22

指定された SIZE がシステムの最大スタックサイズを超えています。 スタックサイズとしてより小さい値を使ってください。

もし必要なら、スレッドの警告は以下のものを:

    no warnings 'threads';

適切なスコープで使うことで抑制できます。

エラー

This Perl not built to support threads

使おうとしている Perl が useithreads 設定オプションを使って ビルドされていません。

スレッド対応にするためには Perl の全てと Perl インストールの全ての XS モジュールを再ビルドする必要があります; これは threads モジュールを 追加するためだけではありません (つまり、スレッド対応 Perl と非対応 Perl は バイナリ互換性がありません。)

Cannot change stack size of an existing thread

現在既にあるスレッドのスタックサイズは変更できないので、以下のようなものは 上述のエラーになります:

    $thr->set_stack_size($size);
Cannot signal threads without safe signals

->kill() シグナルメソッドを使うには安全なシグナルが 有効でなければなりません。 さらなる詳細については "Unsafe signals" を参照してください。

Unrecognized signal name: ...

使おうとしている Perl が ->kill() 呼び出しで使おうとしているシグナルに 対応していません。

バグと制限

バグ報告を投稿することを考える前に、まず相談してください; そしてできれば 遭遇したものが既知の問題かどうかを見るために議論フォーラムにメッセージを 投稿してください。

スレッドセーフなモジュール

スレッド対応アプリケーションで使われるかもしれないモジュールを作るとき、 とくにモジュールが非 Perl データや XS コードを使っているときは、 "Making your module threadsafe" in perlmod を参照してください。

非スレッドセーフなモジュールを使う

残念ながら、スレッドセーフ ではない Perl モジュールに 遭遇するかもしれません。 例えば、実行中に Perl インタプリタがクラッシュしたり、コアダンプして 終了したりするかもしれません。 モジュールとアプリケーションの必要事項に依存して、このような問題を 回避できることがあります。

モジュールがスレッドの中でだけ使われているなら、スレッドエントリ関数の 内側から require (および必要なら import) を使ってモジュールを 読み込んでみてください:

    sub thr_func
    {
        require Unsafe::Module
        # Unsafe::Module->import(...);

        ....
    }

モジュールが main スレッドの内側で必要なら、スレッドを開始してから (再び require->import() を使って) モジュールが 読み込まれるように、そしてその後他のスレッドが開始しないように アプリケーションを修正してみてください。

上述のものが動作しないか、アプリケーションに適切でないなら、問題のある モジュールに対して http://rt.cpan.org/Public/ にバグ報告を 登録してください。

カレントワーキングディレクトリ

MSWin32 以外の全てのプラットフォームでは、カレントワーキングディレクトリの 設定は全てのスレッドで共有されるので、あるスレッドでこれを変更する (つまり chdir() を使う) とアプリケーションの全てのスレッドに 影響します。

MSWin32 では、それぞれのカレントワーキングディレクトリ設定を独自に 管理しています。

環境変数

現在のところ、MSWin32 以外の全てのプラットフォームでは、 スレッドによって作られた (system() または逆クォートによる) 全ての system 呼び出しは main スレッドの環境変数設定を使います。 言い換えると、スレッドで行った %ENV への変更は、そのスレッドで作られた system 呼び出しでは見えません。

これを回避するには、system 呼び出しの一部として環境変数をセットします。 例えば:

    my $msg = 'hello';
    system("FOO=$msg; echo \$FOO");   # Outputs 'hello' to STDOUT

MSWin32 では、各スレッドでは独自の環境変数集合を管理します。

親-子スレッド

プラットフォームによっては、 スレッドがまだ存在している間は スレッドを破壊することができないことがあります。

特殊ブロックの中でスレッドを作る

BEGIN, CHECK, INIT ブロックの内側でスレッドを作成することを 信頼するべきではありません。 Perl バージョンとアプリケーションコードに依存して、成功から(おそらくは 無害な)リークしたスカラの警告、Perl インタプリタのクラッシュまでさまざまな 結果となります。

安全でないシグナル

Perl 5.8.0 から、インタプリタが 安全な 状態になるまでシグナル操作を 延期することでシグナルはより安全になりました。 さらなる詳細については "Safe Signals" in perl58delta"Deferred Signals (Safe Signals)" in perlipc を参照してください。

安全なシグナルはデフォルトの振る舞いで、古い、即時で、安全でないシグナルの 振る舞いは以下の状況でのみ有効です。

安全でないシグナルが有効の場合、シグナルの扱いはスレッドセーフではなく、 ->kill() シグナルメソッドは使えません。

スレッドからクロージャを返す

スレッドからクロージャを返すことを信頼するべきではありmせん。 Perl バージョンとアプリケーションコードに依存して、成功から(おそらくは 無害な)リークしたスカラの警告、Perl インタプリタのクラッシュまでさまざまな 結果となります。

スレッドからオブジェクトを返す

スレッドからオブジェクトを返すのは動作しません。 使うクラスに依存して、(例えば Data::DumperStorable を使って) 直列化されたオブジェクトを返して、join したスレッドでこれを再構成することで これを回避できることがあります。

Perl のバグと CPAN 版の threads

スレッドの対応は このモジュール (つまり threads.pmthreads.xs) のコードを超えて Perl インタプリタ自身に拡張されます。 より古いバージョンの Perl には CPAN から最新版の threads を使っているにも 関わらず自分自身を示すというバグがあります。 Perl を最新版にアップグレードする以外に回避方法はありません。

最新版の Perl でも、スレッドとある種の構造はリークしたスカラや 参照されていないスカラ内観する警告メッセージが出ることがあります。 しかし、このような警告は無害で、安全に無視できます。

必要条件

Perl 5.8.0 以降

SEE ALSO

CPAN の threads ディスカッションフォーラム: http://www.cpanforum.com/dist/threads

threads の注釈付き POD: http://annocpan.org/~JDHEDDEN/threads-1.67/threads.pm

ソースレポジトリ: http://code.google.com/p/threads-shared/

threads::shared, perlthrtut

http://www.perl.com/pub/a/2002/06/11/threads.htmlhttp://www.perl.com/pub/a/2002/09/04/threads.html

Perl スレッドメーリングリスト: http://lists.cpan.org/showlist.cgi?name=iThreads

スタックサイズの議論: http://www.perlmonks.org/?node_id=532956

AUTHOR

Artur Bergman <sky AT crucially DOT net>

threads is released under the same license as Perl.

CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org>

ACKNOWLEDGEMENTS

Richard Soderberg <perl AT crystalflame DOT net> - Helping me out tons, trying to find reasons for races and other weird bugs!

Simon Cozens <simon AT brecon DOT co DOT uk> - Being there to answer zillions of annoying questions

Rocco Caputo <troc AT netrus DOT net>

Vipul Ved Prakash <mail AT vipul DOT net> - Helping with debugging

Dean Arnold <darnold AT presicient DOT com> - Stack size API