DOBON.NET DOBON.NETプログラミング掲示板過去ログ

関数ポインタについて

環境/言語:[XP/C#]
分類:[.NET]

お世話になります。
よろしくお願い致します。

現在、C#でマルチスレッドプログラミングを作成しています。

メインとなるスレッドでWin32APIのCreateThreadを使用して、
新しいスレッドを作成しようと考えています。
ここで問題が発生したのですが、
CreateThreadの引数に入力する関数へのポインタを
C#でどのように表現したらよいかわかりません。

C++の関数ポインタのような表現があるのならば、教えて頂きたく思います。


【目的】
    スレッドを作成した後、スレッド間で通信を行いたい。

【現在の方法】
    現在はWin32APIのPostThreadMesssageを使用した通信を検討しています。
    そこで送信先スレッドのスレッドIDが必要になっています。

    
    
ん…?
System.Threading 名前空間は使えないの…?
■No13367に返信(ガッさんの記事)

ガッさん、早速の返信ありがとうございます。

> ん…?
> System.Threading 名前空間は使えないの…?
説明が不足しすぎました・・・
申し訳ありません。

System.Threading名前空間のクラス(Thread、Monitorなど)があり、
それらのクラスを使用してマルチスレッドプログラミングが作成できることも理解しています。

しかし、System.Threading名前空間のクラスで作成した場合、
データ転送は共通のメンバ変数を使用して受信プロセスがポーリングする形になってしまうのでは?
という事が気になっています。

できればイベントドリブンのような形式にしたいと考えています。
(必要な時にだけ、データを取得する処理が走りその処理を行なう形)
ミ゚Д゚,,彡
"マルチスレッド"…その名前だけ知っている
しったか人間ですたわ言のであんまり参考にならないと思いますが、
書きたいので書かせてください(orz

> しかし、System.Threading名前空間のクラスで作成した場合、
> データ転送は共通のメンバ変数を使用して受信プロセスがポーリングする形になってしまうのでは?
> という事が気になっています。
System.Threading.Threadなどでスレッドを作成すると、
内部でCreateThread()が呼ばれると思います。
仮に、CreateThread()を使ってスレッドを作成したとしても
> データ転送は共通のメンバ変数を使用して受信プロセスがポーリングする形になってしまうのでは?
これは避けられないかもしれませんよ?

> できればイベントドリブンのような形式にしたいと考えています。
> (必要な時にだけ、データを取得する処理が走りその処理を行なう形)
それは「受信プロセス」の仕様によるかと思います。
たとえば、
・ネイティブなWinSock2をマルチスレッドで使う場合。
 (イベントオブジェクトを使わずに)
 待ちうけスレッドでブロッキングモードのソケットに対し、
 accept()をループで回す。
という動作ができます。

…うーん…参考にならないですね(orz
■No13371に返信(ガッさんの記事)

返信ありがとうございます。

とりあえず、
自分が混乱していたことに気づきましたヽ(〜〜。) 


>>しかし、System.Threading名前空間のクラスで作成した場合、
>>データ転送は共通のメンバ変数を使用して受信プロセスがポーリングする形になってしまうのでは?
>>という事が気になっています。
> System.Threading.Threadなどでスレッドを作成すると、
> 内部でCreateThread()が呼ばれると思います。
その通りだと思います。

> 仮に、CreateThread()を使ってスレッドを作成したとしても
>>データ転送は共通のメンバ変数を使用して受信プロセスがポーリングする形になってしまうのでは?
> これは避けられないかもしれませんよ?

>>できればイベントドリブンのような形式にしたいと考えています。
>>(必要な時にだけ、データを取得する処理が走りその処理を行なう形)
> それは「受信プロセス」の仕様によるかと思います。
この点が混乱していました。
CreateThread()でスレッドを生成し、スレッドIDを得て、PostMessageThreadでメッセージを送ったとしても、
受信スレッドはGetMessageで受けるのでイベントドリブンのようにはなりませんよね。

> たとえば、
> ・ネイティブなWinSock2をマルチスレッドで使う場合。
>  (イベントオブジェクトを使わずに)
>  待ちうけスレッドでブロッキングモードのソケットに対し、
>  accept()をループで回す。
> という動作ができます。
>
> …うーん…参考にならないですね(orz
これは初めて知った方法でした。ありがとうございます。
自分で調べてみて、もう一度書き込みをさせて頂きます。
>>それは「受信プロセス」の仕様によるかと思います。
> この点が混乱していました。
> CreateThread()でスレッドを生成し、スレッドIDを得て、PostMessageThreadでメッセージを送ったとしても、
> 受信スレッドはGetMessageで受けるのでイベントドリブンのようにはなりませんよね。

とりあえず、「非同期入出力(非同期I/O)」について調べてみると吉かもしれません。
To:ALL

ガッさんのおかげで混乱から復活し、問題を解決することができました。


======================= <解決方法> =======================

【基本方針】
  System.Threading名前空間のクラスを使用する。
  スレッドの生成はThreadクラスを使用する。
  スレッド間の通信にはMonitorクラスとArrayListクラスを使用する。

【詳細】
  外部と通信(データのやり取り)を行なう機能を追加した独自のスレッドクラス(OriginalThreadクラス)を作成します。
  OriginalThreadクラスは、Threadクラスのインスタンスと通信用ArrayListクラスのインスタンスをメンバ変数として持ち、
  外部との通信用に以下のメソッドを実装します。

  <GetData> このメソッドでは外部から入力されたデータを取得します。
           通信用ArrayListクラスをチェックし、データがあれば取得して処理を行います。
           もしデータが無い場合、Monitor.WaitにThreadクラスをセットして待ち状態にします。

  <SetData> このメソッドでは、通信用ArrayListクラスに外部からのデータを入力します。
           この時、Monitorクラスに待ちスレッドがある場合はMonitor.PulseAllを実行してスレッドの待ち状態を解除します。

======================================================


To:渋木宏明(ひどり)さん

書き込みありがとうございました。

> とりあえず、「非同期入出力(非同期I/O)」について調べてみると吉かもしれません。
調べてみた所、Delegateクラスに関する記述が多数出てきました。
今回作成しようとしているスレッドは、すべて常駐スレッドと考えていますのでDelegateクラスは使用しない方向で考えています。
ただ、今後は必要になることもあると思います。参考になりました。


To:ガッさん

>> たとえば、
>> ・ネイティブなWinSock2をマルチスレッドで使う場合。
>>  (イベントオブジェクトを使わずに)
>>  待ちうけスレッドでブロッキングモードのソケットに対し、
>>  accept()をループで回す。
>> という動作ができます。
>>
>> …うーん…参考にならないですね(orz
>これは初めて知った方法でした。ありがとうございます。
>自分で調べてみて、もう一度書き込みをさせて頂きます。
こらはクライアント/サーバーシステムの技術でしょうか?
私の技量では応用することができそうにありませんでした・・・
解決済み!
  • 題名: Re[7]: 関数ポインタについて
  • 著者: ガッ
  • 日時: 2005/10/21 12:33:23
  • ID: 13386
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
> To:ガッさん
> こらはクライアント/サーバーシステムの技術でしょうか?
> 私の技量では応用することができそうにありませんでした・・・
はい。サーバ側でリスナを待機させる場合に使う方法(らしい)です。
WinSock2で同期ソケットに対してaccept()させるとほぼブロッキングを起こします。
単一のスレッドでユーザインタフェイスも関係していた場合、
ブロッキング中は何も操作できなくなってしまうのですが、
リスニング専用のスレッドを作ればそれを解消することが出来、またプログラムもイベント同期式ではなくなるので簡単になります。

…今回はWinSockではなさそうですので、本当にどうでもいい知識でした(orz
2005/10/21(Fri) 13:13:02 編集(投稿者)

>>とりあえず、「非同期入出力(非同期I/O)」について調べてみると吉かもしれません。
> 調べてみた所、Delegateクラスに関する記述が多数出てきました。
> 今回作成しようとしているスレッドは、すべて常駐スレッドと考えていますのでDelegateクラスは使用しない方向で考えています。
> ただ、今後は必要になることもあると思います。参考になりました。

悲しい検討結果ですね。
私の意図することが正しく伝わらなかったようで残念です。

非同期入出力は、入出力の完了待ちでポーリングなどの無駄な cpu 消費を避けるための重要な技術なので、きちんと調べてみることを勧めます。

DOBON.NET | プログラミング道 | プログラミング掲示板