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

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

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

Re[2]: (マルチ)スレッドの動作状態


(過去ログ 31 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■14772 / inTopicNo.1)  (マルチ)スレッドの動作状態
  
□投稿者/ ロック (1回)-(2008/02/26(Tue) 22:10:53)

分類:[VB.NET/VB2005] 

スレッド(A)をメインイベントproceeger(dllよりRaise)からNewしてStartし、それとほぼ同じタイミングで

再度メインイベントproceegerからNewしてスレッド(A)を呼んだ場合(ほぼ同時イベントが起きた場合)、

スレッドの処理は正しく処理されるのでしょうか?


ConsoleWriteLineで追ってみると、後から来たイベントのスレッドが先に終わっている結果もありました。(同じ処理で)

スレッド終了後に出る「スレッド 0x15f4 はコード 0 (0x0) で終了しました。」というメッセージの出るタイミングもバラバラです。

また「スレッド '<名前がありません>' (0x1744) はコード 0 (0x0) で終了しました。」という記述もあり、スレッドの管理のされ方

に途方にくれています。


ご存知の方がいれば、ご教授下さい。
引用返信 編集キー/
■14773 / inTopicNo.2)  Re[1]: (マルチ)スレッドの動作状態
□投稿者/ Tom Yama (30回)-(2008/02/26(Tue) 22:31:46)
No14772 (ロック さん) に返信
物事を順番に処理したいのならば、スレッドは使わない。
引用返信 編集キー/
■14774 / inTopicNo.3)  Re[1]: (マルチ)スレッドの動作状態
□投稿者/ Jitta (456回)-(2008/02/26(Tue) 22:36:26)
Jitta さんの Web サイト
No14772 (ロック さん) に返信
> スレッド(A)をメインイベントproceeger(dllよりRaise)からNewしてStartし、それとほぼ同じタイミングで
>
> 再度メインイベントproceegerからNewしてスレッド(A)を呼んだ場合(ほぼ同時イベントが起きた場合)、
>
> スレッドの処理は正しく処理されるのでしょうか?
>
>
> ConsoleWriteLineで追ってみると、後から来たイベントのスレッドが先に終わっている結果もありました。(同じ処理で)
>
> スレッド終了後に出る「スレッド 0x15f4 はコード 0 (0x0) で終了しました。」というメッセージの出るタイミングもバラバラです。
>
> また「スレッド '<名前がありません>' (0x1744) はコード 0 (0x0) で終了しました。」という記述もあり、スレッドの管理のされ方
>
> に途方にくれています。
>
>
> ご存知の方がいれば、ご教授下さい。

 「正しく処理されるのでしょうか?」については、ここに書かれている結果からは、「正しく処理されている」と判断されます。
なので、どのような処理のされ方を望んでいらっしゃるのか、書いていただけるでしょうか。あなたが望んでいることと、実際の処理の差が、回答になります。
引用返信 編集キー/
■14778 / inTopicNo.4)  Re[2]: (マルチ)スレッドの動作状態
□投稿者/ HiJun (94回)-(2008/02/26(Tue) 23:19:06)
それぞれのスレッドとしてうごいているのだから、どちら先に処理を終了しても
正解ではと思います。
その動きがいやなら、排他をかけたりとか、複数のスレッドにしているのを1つの
スレッドにまとめたほうが良いのではないかと思います。
引用返信 編集キー/
■14783 / inTopicNo.5)  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スレッド)とは分離して処理する、という観点でスレッドを分けることには意味はあるかもしれません。

引用返信 編集キー/
■14808 / inTopicNo.6)  Re[2]: (マルチ)スレッドの動作状態
□投稿者/ ロック (2回)-(2008/02/27(Wed) 11:44:51)
No14783 (七曜 さん) に返信

とても丁寧な説明ありがとうございます。OSの特性上、CPUの状況次第でスレッド処理の順序関係が前後することが分かり、役に立ちました。


実装概要を説明します。

・環境
 OS:Win-xp Pro
CPU:Centrino Duo

・処理の流れ

 クライアントA →    DLL → サーバアプリ →  サーバアプリ
 クライアントB → (VB6)  → (main:VB.NET) →  (スレッドA)
   ・
   ・
   ・   Z


複数クライアントから不定期に(同時もある)アクセスがあり、DLLで順次Winsockで処理し、サーバアプリにイベント渡しする。
メイン処理からスレッドを呼んでいる。メイン処理が終了次第DLLに戻る。

各アクセスの処理の状態(例えば固まっても)が他アクセスの処理に影響を与えないようにスレッドを採用した。

メイン処理部での処理は小さく、基本処理は全てスレッドで行う。


以上のような感じです。


ありがとうございます。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -