Thread-Conveyor-0.17 > Thread::Conveyor

名前

Thread::Conveyor - スレッド間における任意のデータ構造の移送

概要

    use Thread::Conveyor;
    my $belt = Thread::Conveyor->new(
     {
      maxboxes => 50,
      minboxes => 25,
      optimize => 'memory', # または 'cpu'
     }
    );

    $belt->put( "foo", ["bar"], {"zoo"} );
    my ($foo,$bar,$zoo) = $belt->take;
    my ($foo,$bar,$zoo) = $belt->take_dontwait;
    my ($foo,$bar,$zoo) = $belt->peek;
    my ($foo,$bar,$zoo) = $belt->peek_dontwait;
    my $onbelt = $belt->onbelt;

    my @box = $belt->clean;
    my @box = $belt->clean_dontwait;
    my ($foo,$bar,$zoo) = @{$box[0]};

    $belt->maxboxes( 100 );
    $belt->minboxes( 50 );

    $belt->shutdown;
    $belt->thread;
    $belt->tid;

説明

                  *** A note of CAUTION ***

 This module only functions on Perl versions 5.8.0 and later.
 And then only when threads are enabled with -Dusethreads.  It
 is of no use with any version of Perl before 5.8.0 or without
 threads enabled.

                  *************************

                  *** 注   意   書   き ***

 このモジュールはPerl 5.8.0とそれ以降でのみ機能する。
 かつ、-Dusethreadsでスレッドが有効になっている場合だけである。
 5.8.0より前のバージョン、あるいはスレッド機能が有効になって
 いない場合は、利用できない。

                  *************************

The Thread::Conveyor object is a thread-safe data structure that mimics the behaviour of a conveyor belt. One or more worker threads can put boxes with frozen values and references on one end of the belt to be taken off by one or more worker threads on the other end of the belt to be thawed and returned.

Thread::Conveyorオブジェクトは、ベルトコンベアの振る舞いをまねた スレッドセーフなデータ構造である。一つ以上のワーカースレッドが凍結された 値やリファレンスの入った箱をベルトの一方の端に置く。そしてベルトの 他方の端で一つ以上のワーカースレッドがその箱を取り除き、解凍して返す。

A box may consist of any combination of scalars and references to scalars, arrays (lists) and hashes. Freezing and thawing is currently done with the Thread::Serialize module, but that may change in the future. Objects and code references are currently not allowed.

一つの箱はスカラーおよび、スカラー、配列(リスト)そしてハッシュへの リファレンスのコンビネーションで構成される。凍結と解凍は現在のところ Thread::Serializeモジュールを使ってなされる。しかし将来は変更されるかも しれない。オブジェクトとコードリファレンスは現在のところ許されない

By default, the maximum number of boxes on the belt is limited to 50. Putting of boxes on the belt is halted if the maximum number of boxes is exceeded. This throttling feature was added because it was found that excessive memory usage could be caused by having the belt growing too large. Throttling can be disabled if so desired.

デフォルトでは、ベルト上の箱の最大値は50に制限される。箱の最大値を 超過した場合、ベルトに箱を置く作業は停止する。この抑制機能(スロットル)を 追加したのは、ベルトが非常に大きくなることによって過度のメモリ消費が発生 することに気付いたからである。もしそう望むならスロットルを無効にできる。

クラスメソッド

new

 $belt = Thread::Conveyor->new(
  {
   maxboxes => 50,
   minboxes => 25,
   optimize => 'memory', # あるいは 'cpu'
  }
 );

The "new" function creates a new empty belt. It returns the instantiated Thread::Conveyor object.

"new"関数は新しい空のベルトを生成する。初期化されたThread::Conveyor オブジェクトを返す。

The input parameter is a reference to a hash. The following fields are optional in the hash reference:

入力するパラメータはハッシュのリファレンスである。以下のフィールドが ハッシュリファレンス内のオプション

maxboxes
 maxboxes => 50,

 maxboxes => undef,  # スロットルを無効にする

The "maxboxes" field specifies the maximum number of boxes that can be sitting on the belt to be handled (throttling). If a new put would exceed this amount, putting of boxes will be halted until the number of boxes waiting to be handled has become at least as low as the amount specified with the "minboxes" field.

"maxboxes"フィールドはベルトに据えられる箱の最大値を指定し、 制御(スロットル)を行う。もし新たなputがこの値を超過した場合、 制御されるために待っている箱の数が少なくとも"minboxes"フィールドで 指定された値に下がるまで、箱を置く作業は停止する。

Fifty boxes will be assumed for the "maxboxes" field if it is not specified. If you do not want to have any throttling, you can specify the value "undef" for the field. But beware! If you do not have throttling active, you may wind up using excessive amounts of memory used for storing all of the boxes that have not been handled yet.

何も指定しないなら"maxboxes"フィールドは50箱と見なされる。もしスロットル を望まないなら、フィールドに"undef"を指定する。だけど気を付けて! スロットルを活動させないと、もはや制御の効かない箱を全て保持するために 大量のメモリを消費するはめになるかもしれない。

The maxboxes method can be called to change the throttling settings during the lifetime of the object.

ベルトオブジェクトが生きている間、maxboxesメソッドを呼び出して スロットルの設定を変更できる。

minboxes
 minboxes => 25, # default: maxboxes / 2

The "minboxes" field specifies the minimum number of boxes that can be waiting on the belt to be handled before the putting of boxes is allowed again (throttling).

"minboxes"フィールドは、箱に対するputが再度許可される前に ベルト上で制御(スロットル)されるのを待っている箱の最小値を指定する。

If throttling is active and the "minboxes" field is not specified, then half of the "maxboxes" value will be assumed.

スロットルが活性化していて、かつ"minimumboxes"フィールドが指定されていない 場合、"maxboxes"の値の半分が仮定される。

The minboxes method can be called to change the throttling settings during the lifetime of the object.

ベルトオブジェクトが生きている間、minboxesメソッドを読んでスロットルの 設定を変更できる。

optimize
 optimize => 'cpu', # デフォルト:Perlのバージョンによる

The "optimize" field specifies which implementation of the belt will be selected. Currently there are two choices: 'cpu' and 'memory'. For Perl 5.8.0 the default is "memory". For higher versions of perl, the default optimization is "cpu". The reason for this was that Perl 5.8.0 has a severe memory leak with shared arrays, which is what is being used with the "cpu" optimization.

"optimize"フィールドは、ベルトの実装をどちらにするか指定する。現在のところ、 二つの選択肢がある:'cpu'と'memory'だ。Perl 5.8.0ではデフォルトで"memory"に なる。それ以上のバージョンでは、デフォルトは"cpu"になる。このようにした 理由は、Perl 5.8.0が共有配列で深刻なメモリリークを引き起こし、"cpu"最適化を 使うとそれが起きるからである。

You can call the class method optimize to change the default optimization.

クラスメソッドoptimizeを呼べば、デフォルトの最適化を変更できる。

optimize

 Thread::Conveyor->optimize( 'cpu' );

 $optimize = Thread::Conveyor->optimize;

The "optimize" class method allows you to specify the default optimization type that will be used if no "optimize" field has been explicitely specified with a call to new. It returns the current default type of optimization.

"optimize"クラスメソッドを使えば、デフォルトの最適化タイプを指定できるので、 newを呼んだときに明示的に"optimize"フィールドを指定しなくても、それを 使うことができる。現在の最適化のデフォルトタイプを返す。

Currently two types of optimization can be selected:

現状では二つのタイプの最適化を選択できる:

memory

Attempt to use as little memory as possible. Currently, this is achieved by starting a seperate thread which hosts an unshared array. This uses the "Thread::Conveyor::Thread" sub-class.

可能な限り少なくメモリを使おうと試みる。現在、この機能は非共有配列のホスト となる独立したスレッドを開始することによって達成している。これには "Thread::Conveyor::Thread"サブクラスを用いる。

cpu

Attempt to use as little CPU as possible. Currently, this is achieved by using a shared array (using the "Thread::Conveyor::Array" sub-class), encapsulated in a hash reference if throttling is activated (then also using the "Thread::Conveyor::Throttled" sub-class).

可能な限りCPUを少なく使おうと試みる。現在、この機能は共有配列を使うことに よって達成している("Thread::Conveyor::Array"サブクラスを利用)。もし スロットルが活性化しているなら、ハッシュリファレンスの中にカプセル化 される(そのときは"Thread::Conveyor::Throttled"サブクラスも利用する)。

オブジェクトメソッド

The following methods operate on the instantiated Thread::Conveyor object.

以下のメソッドは、初期化されたThread::Conveyorオブジェクトに対し操作する。

put

 $belt->put( 'string',$scalar,[],{} );

The "put" method freezes all the specified parameters together in a box and puts the box on the beginning of the belt.

"put"メソッドは、指定したパラメータを全て一緒に箱の中で凍結し、その箱を ベルトの始まりに置く。

take

 ($string,$scalar,$listref,$hashref) = $belt->take;

The "take" method waits for a box to become available at the end of the belt, removes that box from the belt, thaws the contents of the box and returns the resulting values and references.

"take"メソッドは、ある箱がベルトの端で利用可能になるまで待ち、その箱を ベルトから取り除き、箱の中身を解凍し、その結果の値やリファレンスを返す。

take_dontwait

 ($string,$scalar,$listref,$hashref) = $belt->take_dontwait;

The "take_dontwait" method, like the take method, removes a box from the end of the belt if there is a box waiting at the end of the belt. If there is no box available, then the "take_dontwait" method will return immediately with an empty list. Otherwise the contents of the box will be thawed and the resulting values and references will be returned.

"take_dontwait"メソッドは、takeメソッド同様、ベルトの最後で待っている箱が あるなら、箱をベルトの端から取り除く。利用可能な箱がない場合、 "take_dontwait"メソッドは直ちに空リストを返す。それ以外なら箱の中身は 解凍され、結果の値やリファレンスが返される。

clean

 @box = $belt->clean;
 ($string,$scalar,$listref,$hashref) = @{$box[0]};

The "clean" method waits for one or more boxes to become available at the end of the belt, removes all boxes from the belt, thaws the contents of the boxes and returns the resulting values and references as an array where each element is a reference to the original contents of each box.

"clean"メソッドは、ベルトの最後で一つ以上の箱が利用可能になるまで待ち、 ベルトから全ての箱を取り除き、箱の中身を解凍し、結果の値やリファレンスを 配列として返す。この配列の各要素は、各箱の元の内容へのリファレンスである。

clean_dontwait

 @box = $belt->clean_dontwait;
 ($string,$scalar,$listref,$hashref) = @{$box[0]};

The "clean_dontwait" method, like the clean method, removes all boxes from the end of the belt if there are any boxes waiting at the end of the belt. If there are no boxes available, then the "clean_dontwait" method will return immediately with an empty list. Otherwise the contents of the boxes will be thawed and the resulting values and references will be returned an an array where each element is a reference to the original contents of each box.

"clean_dontwait"メソッドは、clean同様、ベルトの最後で待っている箱が あるなら、ベルトの端から全ての箱を取り除く。もし利用可能な箱がないなら、 "clean_dontwait"メソッドは直ちに空リストを返す。それ以外の場合、箱の中身は 解凍され、結果の値やリファレンスは配列として返される。この配列の各要素は、 各箱の元の内容へのリファレンスである。

peek

 ($string,$scalar,$listref,$hashref) = $belt->peek;

 @lookahead = $belt->peek( $index );

The "peek" method waits for a box to become availabe at the end of the belt, but does not remove it from the belt like the take method does. It does however thaw the contents and returns the resulting values and references.

"peek"メソッドは、ベルトの最後で箱が利用可能になるまで待つ。しかし、take メソッドとは違い、ベルトから箱を取り除かない。だが、内容を解凍し、 結果の値やリファレンスは返す。

For advanced, and mostly internal, usages, it is possible to specify the ordinal number of the box in which to peek.

さらに進んだ、ほとんど内部的な利用方法として、のぞき見する箱の序数が 指定可能だ。

Please note that there is no guarantee that "take" will give you the same data as which is returned with this method, as any other thread can have taken the boxes off of the belt in the meantime.

注意して貰いたいのは、このメソッドが返したデータと同じものを"take"が 返すことは保証されていないということである。というのも、他のスレッドが、 その間にベルトから箱を取り除く可能性があるからだ。

peek_dontwait

 ($string,$scalar,$listref,$hashref) = $belt->peek_dontwait;

 @lookahead = $belt->peek_dontwait( $index );

The "peek_dontwait" method is like the take_dontwait method, but does not remove the box from the belt if there is one available. If there is a box available, then the contents of the box will be thawed and the resulting values and references are returned. An empty list will be returned if there was no box available at the end of the belt.

"peek_dontwait"メソッドは、take_dontwaitメソッドに似ている。ただし 箱が利用可能な場合、ベルトから箱を取り除かない。箱が利用可能なら、 箱の中身は解凍され、結果の値やリファレンスが返される。もしベルトの最後に 利用可能な箱が内なら、空リストが返される。

For advanced, and mostly internal, usages, it is possible to specify the ordinal number of the box in which to peek.

さらに進んだ、ほとんど内部的な利用方法として、のぞき見する箱の序数を指定 可能だ。

Please note that there is no guarantee that "take" will give you the same data as which is returned with this method, as any other thread can have taken the boxes off of the belt in the meantime.

注意して貰いたいのは、このメソッドが返したデータと同じものを"take"が 返すことは保証されていないということである。というのも、他のスレッドが、 その間にベルトから箱を取り除く可能性があるからだ。

onbelt

 $onbelt = $belt->onbelt;

The "onbelt" method returns the number of boxes that are still in the belt.

"onbelt"メソッドは、まだベルトに残っている箱の数を返す。

maxboxes

 $belt->maxboxes( 100 );
 $maxboxes = $belt->maxboxes;

The "maxboxes" method returns the maximum number of boxes that can be on the belt before throttling sets in. The input value, if specified, specifies the new maximum number of boxes that may be on the belt. Throttling will be switched off if the value undef is specified.

"maxboxes"メソッドは、スロットルが開始されるまでベルトの上に載せられる 箱の最大値を返す。入力値が指定されると、新たな最大値が設定される。 入力値にundefを指定することで、スロットルのスイッチが切られる。

Specifying the "maxboxes" field when creating the object with new is equivalent to calling this method.

newを使ってオブジェクトを生成する時に"maxboxes"フィールドを指定するのは、 このメソッドを呼び出すのに等しい。

The minboxes method can be called to specify the minimum number of boxes that must be on the belt before the putting of boxes is allowed again after reaching the maximum number of boxes. By default, half of the "maxboxes" value is assumed.

minboxesメソッドは、箱が最大値に達した後、再び箱を置くのが許可される までの、ベルト上になければならない箱の最小値を設定するために呼び出される。 デフォルトでは、"maxboxes"の半分の値が想定される。

minboxes

 $belt->minboxes( 50 );
 $minboxes = $belt->minboxes;

The "minboxes" method returns the minimum number of boxes that must be on the belt before the putting of boxes is allowed again after reaching the maximum number of boxes. The input value, if specified, specifies the new minimum number of boxes that must be on the belt.

"minboxes"メソッドは、箱が最大値に達した後、再び箱を置くのが許可される までの、ベルト上になければならない箱の最小値を返す。入力値を指定すると、 新たな最小値が設定される。

Specifying the "minboxes" field when creating the object with new is equivalent to calling this method.

newを使ってオブジェクトを生成する時に"minboxes"フィールドを指定するのは、 このメソッドを呼び出すのに等しい。

The maxboxes method can be called to set the maximum number of boxes that may be on the belt before the putting of boxes will be halted.

maxboxesメソッドを呼び出すと、箱の設置が停止するまでにベルト上に存在 できる箱の最大値を設定できる。

shutdown

 $belt->shutdown;

The "shutdown" method performs an orderly shutdown of the belt. It waits until all of the boxes on the belt have been removed before it returns.

"shutdown"メソッドは、ベルトの操業を正常に停止させる。このメソッドは 戻る前に、ベルト上の箱が全て取り除かれるまで待ちに入る。

thread

 $thread = $belt->thread;

The "thread" method returns the thread object that is being used for the belt. It returns undef if no seperate thread is being used.

"thread"メソッドは、そのベルトを使っているスレッドオブジェクトを返す。 どのスレッドも利用していないならundefを返す。

tid

 $tid = $belt->tid;

The "tid" method returns the thread id of the thread object that is being used for the belt. It returns undef if no seperate thread is being used.

"tid"メソッドは、そのベルトを利用しているスレッドオブジェクトのスレッド idを返す。どのスレッドも利用していないならundefを返す。

必要なモジュール

 load (どのバージョンでも)
 Thread::Serialize (どのバージョンでも)
 Thread::Tie (0.09)

最適化

This module uses load to reduce memory and CPU usage. This causes subroutines only to be compiled in a thread when they are actually needed at the expense of more CPU when they need to be compiled. Simple benchmarks however revealed that the overhead of the compiling single routines is not much more (and sometimes a lot less) than the overhead of cloning a Perl interpreter with a lot of subroutines pre-loaded.

このモジュールはloadを使ってメモリとCPUの消費を縮小している。これに よって、サブルーチンは、実際に必要となるときにだけスレッド内でコンパイル される。このコンパイルのためにより多くのCPUを犠牲にする。しかし単純な ベンチマークによると、一つのルーチンをコンパイルするオーバーヘッドは 予めロードされた大量のサブルーチンを伴うPerlインタプリタをクローンする オーバーヘッドよりもそれほど多くはない(そして時には非常に少なくなる)ことが 明らかになっている。

警告

Passing unshared values between threads is accomplished by serializing the specified values using Thread::Serialize. Please see the CAVEATS section there for an up-to-date status of what can be passed around between threads.

スレッド間で非共有の値を渡すのは、Thread::Serializeを使って指定の値を シリアル化することで達成している。スレッド間で何を渡せるかの最新状況に ついては、そちらのモジュールの注意セクションを参照して欲しい。

作者

Elizabeth Mattijsen, <liz@dijkmat.nl>.

Please report bugs to <perlbugs@dijkmat.nl>.

歴史

This module started life as Thread::Queue::Any and as a sub-class of Thread::Queue. Using the conveyor belt metaphore seemed more appropriate and therefore the name was changed. To cut the cord with Thread::Queue completely, the belt mechanism was implemented from scratch.

このモジュールはThread::Queue::Anyとして、そしてThread::Queueの サブクラスとして、誕生した。ベルトコンベアの比喩はより適したものに思えた ので、名前を変えた。Thread::Queueのコードを完全に断ち切るために、ベルトの メカニズムは一から実装した。

Why would you use Thread::Conveyor over Thread::Queue::Any? Well, Thread::Conveyor has the following extra features:

なぜThread::Queue::AnyよりThread::Conveyorを使うのか? ええと、 Thread::Conveyorには以下の付加的な特徴があるのだ:

It works with Perl 5.8.0

Perl 5.8.0で動作する

Shared arrays leak memory very badly in Perl 5.8.0. Therefore, you cannot really use Thread::Queue in Perl 5.8.0, and consequently cannot use Thread::Queue::Any in any type of production environment.

Perl 5.8.0では共有配列が大変まずい具合にメモリリークを起こす。それゆえ、 本当はPerl 5.8.0ではThread::Queueは使えない。そしてその結果、 どんなプロダクション環境タイプでも、Thread::Queue::Anyは使えない。

It provides throttling

スロットルの提供

A thread that enqueues very many values quickly, can cause a large amount of memory to be used. With throttling, any thread that enqueues will have to wait until there is "room" on the belt again before continuing. See methods "minboxes" and "maxboxes".

スレッドが急に大変多くの値をキューに入れると、大量のメモリが消費される。 スロットルを使うことで、キューに入れようとするスレッドは作業を続ける前に、 ベルトに"余裕"ができるまで、待たなければならない。メソッド"minboxes"と "maxboxes"を参照されたし。

You can check for a new value without removing it from the belt

ベルトから取り除くことなしに新しい値をチェックできる

Sometimes it can be nice to check whether there is a new value on the belt without actually removing it from the belt. See the "peek" and "peek_dontwait" methods.

実際にベルトから取り除かずに、ベルト上に新しい値があるかどうかを調べると 良いことが、時々ある。"peek"と"peek_dontwait"メソッドを参照されたし。

You can reset the entire belt

ベルトを丸ごとリセットできる

Sometimes you want to be able to reset the contents of the belt. See the "clean" and "clean_dontwait" methods for that.

時にはベルトの中身をリセットしたいと思うだろう。そのためにはメソッド "clean"と"clean_dontwait"を参照されたし。

You can get everything from the belt in one go

一気にベルトから全てを得られる

Sometimes you want everything that's on the belt in one go. That can also ba accomplished with the "clean" and "clean_dontwait" methods.

時にはベルト上にある全てのものを一気に欲しいと思うだろう。これもまた "clean"と"clean_dontwait"メソッドを使って達成できる。

著作権

Copyright (c) 2002-2004 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

参照

threads, threads::shared, Thread::Queue, Thread::Queue::Any, Thread::Serialize.