[1390] Re:マルチスレッドについて
投稿者:山
2009/07/17 20:30:56
>ここで、スレッドを3本起動しており、「タイマ表示」という関数名の関数を
>呼び出しているようですが、その「タイマ表示」関数は、引数のqidを順に
>変えながら、3回呼び出されているように見えますが……(そして毎回、自ら
>returnしている)
ああ、やっぱりそう見えましたか。実は裏のデバックトレースが重過ぎて
実行が周期内に終わっていないのです。常にオーバフロー状態なんです。
で、デバックトレースOFFにすると、表示自体がデバックモニターの分類3
を使っているので、表示も消えてしまうと言うジレンマが…
なので、最後にデバックトレースのサンプルを出したのですが、やはり^^;
実際は、VMの実行がトレースのためにめちゃくちゃ遅いのです。プログラムの
途中で処理が変わるどころか、バイトコード1命令の実行の中で2-4回VMが
変わって、VMがそれぞれの担当処理を実行しようとがんばっています。
しかし、デバックトレースは、UDP通信でデバックモニターに送っているので、
その通信をしたタイミング(通信処理のためのスレ一時中断)でスレッド
チェンジが起こってしまっています。デバック情報1行送るたびにスレッドが
ころころ変わってしまっています。
まあでも、とてもいいデバック環境でした、ほんの些細なタイミングミスも、
ころころ引っかかるので、もう異常が出まくりでした。つぶすのは大変で
したが、つぶし終わった後いろいろ変えてもなんら問題がおきませんでした。
で、そのまま使ってたデータで文を作ってUPした後、これまずいかなーと
思って、デバックトレースサンプルを追加してみました。
間違いなく、main+3スレッド=4スレッド、細切れどころかミジン切れの
状態で動いています。後で、タイミングを長くしたものの出力でもUPします。
今ちょっとノートPCシステム入れ直ししてて、それにかかりっきりで…
手順を簡単に説明すると。下のスレ開始から
> sid[0] = スレ開始("タイマ表示",40,6," 40ms"," で6回実行");
1、スレッド初期起動キューが作成される
2、空きVMがキューをGET位して、タイマ表示関数を実行
3.タイマ表示関数は初期起動なので、システム変数を生成し
初期化とパラメーターをセーブして、待機終了 returnする
4、管理部分が、周期起動のスレッドが有るので、そのスレッド向けに
時間が来たら、周期起動のキューを作る。
5.空きVMが周期起動キューを取り出し、その関数を実行する。
6.タイマ表示関数は周期起動キューで起動されたことを理解して
カウンタを+1して、そのカウンタを表示する。そして待機return
7.また4に戻り周期キューが作成されるー>4に戻り
8.タイマ表示関数は周期起動キューの中で、回数値とカウンタを
比較してカウンタ>=回数なら、終了returnして、スレッドが終わる。
こんな感じで動いています。たぶん説明が抜けていたのは、システムが
周期キューを生成している部分だと思います。
例えば、6回実行のスレは、初期1回とタイマー6回で、合計7回実行
しています。
スレ1が7回、スレ2が6回、スレ3が5回実行しています。
で、タイマ表示関数は周期に追いついていないので、システムは回数以上
の周期タイマーキューを生成していて、VMが実行しようとしています。
また、ちがうVMが同じスレッドの周期キューを平行して実行しようと
してしまいます。もちろんこれは問題が起こるので、そうならないように
作られています。言葉で言うと簡単そうですが、複雑な制御をしています。
常に重い状態で動いているので、キューが溜まってヘビーな状態で
デバックをしていました。
>「タイマ表示」関数がreturnしないまま、別のスレッドに制御を奪われることって
>あるんでしょうか?
もう、1回のキュー処理で数十回はVMのスレッドチェンジが起こっています。
各スレッド処理は、みじん切りの細切れで並列に動いています。
デバックトレースを止めればそのようなことは無いと思います。
デバックトレースを止めた時に、どの様なタイミングで切り替わるかは
興味があります。しかしそれを調べるためには、表示は一切使えないんで
すねね、なんに表示してもその間に切り替わるから。オンメモリーだけで
高速のトレーサでも作りこまないと、それでも、VMの方が早いかもしれ
ない。