C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 31 を表示中)
■14783 / )  Re[1]: (マルチ)スレッドの動作状態
□投稿者/ 七曜 (88回)-(2008/02/26(Tue) 23:59:19)
No14772 (ロック さん) に返信
> スレッド(A)をメインイベントproceeger(dllよりRaise)からNewしてStartし、それとほぼ同じタイミングで
>
> 再度メインイベントproceegerからNewしてスレッド(A)を呼んだ場合(ほぼ同時イベントが起きた場合)、
>
> スレッドの処理は正しく処理されるのでしょうか?

Windowsで使用されているのは、プリエンプティブ・マルチタスクという処理方式で
各プロセスに一定時間のCPU時間を割り当てる、という方式です。
マルチスレッド処理を実装した場合、この方式で割り当てられたCPU時間を
さらに各スレッド間で割り振る事になります。
優先度(ThreadPriority)が同じスレッドには、平等にCPU時間が割り当てられますが(ここはOSのスケジューラが管理しています)
割り当てられたCPU時間内に、各スレッドの処理(ステートメントというかCPUレベルの命令になりますけど)が
完全に同じ処理時間で処理される事は保障されないでしょう。
主な理由は、おそらくリソース(Memory、Disk I/O、Device I/Oなど)を要求した場合に、
処理対象のスレッドに対して、利用可能として渡されるまでの時間が異なるからだと推測されますが
実際に例ほどの大きな差はでませんがわかりやすく簡素化して記述しますと
 スレッドAが変数を割り当てる(Memory確保要求が実施される)→1秒かかった
 スレッドBが変数を割り当てる(Memory確保要求が実施される)→2秒かかった
この時点で、仮にスレッドBの方が先に開始されていても、次の処理(例えば別の変数を割り当てる、など)は
スレッドAの方が先に進む可能性が高い事がわかると思います。
その後の処理が同じ時間で処理されたとした場合、やはりスレッドAが先に終了するでしょう。
Single Core Processorであれば、考え方は割と単純ですが、最近では当たり前感のあるMulti Core Processorであれば
さらに状況は複雑化し、各Coreの空き状況によってスレッドが処理されますので、
同じ様にCPU時間の割り当てはされますが、その処理順序は、より保証されなくなります。

あまり厳密ではないかもしれませんが、概念的にはこんな感じになるかと思います。
つまり、先に開始したスレッドが必ず先に処理される保証はない、と理解して頂ければ良いと思います。
そういった点から、「スレッドの処理は正しく処理されるのでしょうか?」に関しての回答は「正しく処理されていると思われます」となります。

蛇足ではありますが、メインスレッド内のメッセージループは(通常は)1つなので、イベントメッセージはシリアライズ(直列化)されます。
従って、見かけ上、同時にイベントが発生してもイベントハンドラへの突入には順序が発生します。
この順序もイベントメッセージを投入しているスレッドが複数あれば上記の様に必ずしも先にメインスレッドへメッセージを投入できるとは
限らない事になる、と思っていた方が良いかと思います。
(普通は、ユーザーがイベント発生させるタイミングよりも、もっと短い単位でスレッド切り替え(スレッドコンテキスト)が発生するので
 大体は見掛け上と同じと考えて差し支えありませんが。)

以上の点から、順序性のある処理をしたい場合には、その処理に関してはマルチスレッド化は向かない可能性が高いです。
(同期処理とかを工夫すれば、順序性を保ちつつ処理できる可能性はありますが、そこまでの実装コストを考えるとどうでしょうかね、というレベル。)
もちろん、順序性の関係無いスレッド(例えばUIスレッド)とは分離して処理する、という観点でスレッドを分けることには意味はあるかもしれません。

返信 編集キー/


管理者用

- Child Tree -