アプリ版:「スタンプのみでお礼する」機能のリリースについて

以下の様なコードを用いてthreadを走らせています。

my $cond = 0;

while($cond == 0){
 {
  my $thread;
  my @threads;
  my $index = 0;
  while ($index < @param1){
   $thread = threads->new(\&func, $param1[$index++], $param2);
   push @threads, $thread;
  }
 
  sleep(1);
 
  while (@threads > 0){
   $thread = pop @threads;
   $thread->join();
  }
 }
 condcheck();
}

条件が満たされるまで、一定の処理を行うthreadを複数走らせるというものなのですが、
これを実行すると、perlの使用しているメモリがどんどん増えて行っているのを確認しました。
#@threadsや$threadのスコープが外れるようにしているのになぜ?
newしたthreadオブジェクトを、明示的に削除したいのですが、どのようにすればよいでしょうか?

A 回答 (5件)

参照カウンターは、メモリー実体とperlの変数とを


結び付けているリンクの数と考えてください。
perlの変数がスコープから外れて削除されると。
メモリー実体の参照カウンターが一つ減ります。
そしてカウンターが0になればメモリー実態が削除されます。
この処理を行っているのがガーベージコレクションです。
メモリー実体を削除するときガーベージコレクションは、
DESTROY関数の定義があれば実行します。
パッケージは普通DESTROY関数を定義しません、
なぜならものすごく遅くなるからです。
今回のようにメモリが削除されているかどうかを確かめる
ためにパッケージにDESTROY関数を追加するのもよいかも
しれません。
パッケージを修正するのに抵抗があるのならカレントディリクトリに threads.pm をコピーし
perl -I . test.pl のように実行してみてはいかがでしょうか。
    • good
    • 0

メモリ変数がガーベージコレクションの対象に


ならないと言ううことは、参照カウンターが
0にならないことを意味します。
func関数の中でmainの名前空間を使用していないかどうか
確認してもらえますか。
問題ないようでしたら、 threadsモジュールに
DESTROY処理を追加してオブジェクトがきちんと破棄されているかどうか確認してはどうでしょうか。

それから前の私の発言に誤りがありました
下記の通り配列の要素数になることを確認しました。
すみません。
@a=(1,2,3,4);
$cnt=@a;
printf("%d\n", $cnt);
4

この回答への補足

「func関数の中でmainの名前空間を使用していないかどうか」というのはfunc呼び出し側(or親スレッド)内の変数や関数を使って呼び出していないか...ということでしょうか?(関数は呼び出しています)

そのほかに、以下のように定義した共有変数をlockを使ってアクセスしあっています。
my $signal : shared = 0;

>threadsモジュールにDESTROY処理を追加して
DESTOROYはC++言語で言う所のデストラクタなんですね。
threadモジュールにコードを追記する...って事ですか?
そゆ事ってやっちまっても良いものなんですか?
ちょっとperlの文化を理解するほど深くいじっていないもので...。

補足日時:2004/06/12 01:32
    • good
    • 0

main::(-e:1): 0


DB<1> @a=(1,2,3,4);

DB<2> printf("%d\n", @a);
1
    • good
    • 0

#1 の方へ:


配列変数をスカラーコンテキストで評価するとその配列の要素数になります.
だから
while ($index < $#param1) {
でも
while ($index < @param1) {
でも同じことではあります. まあ前者の方が誤解される可能性は少ないと思いますが.

それはさておき, perl の使っているメモリが増えているのはどのように確認したのでしょうか?
プログラムによってはメモリが不要になってもシステム (OS) に返さないことがあります.
手のあいているときに garbage collector を走らせればいいはずなんですが, perl で
明示的に garbage collector を走らせることってできたっけ....

この回答への補足

Cygwin on Windows XPでいろいろ試していますが、
perl の使っているメモリが増えているのは
perfmonをって、該当するperl processのworking setをモニタリングして確認しました。

perl はほとんど使い始めたばかりなので、何をするにも入門書&googleが手放せないのですが、
@param1の評価方法は "perl 配列 要素数"とかでググッた結果で出てくるページに載っていたもののはずです。

一応、{}を使って、配列(@threads)と変数($thread)の寿命を切ってみたつもりだったのですが、効果がなかったので泣けてます...。
thread関数内ではgcは効かないのでしょうか...。

補足日時:2004/06/12 01:22
    • good
    • 0

配列とスカラー変数を比較していますが


while ($index < $#param1){
の間違いではないですか。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!