• ベストアンサー

Linuxでのスレッド間メッセージについて

Linuxでスレッドを複数生成し、スレッド間でメッセージのやり取りをしたいと思っています。 ネットで色々検索したのですが、欲しい情報にめぐり合えていません。 # WindowsのPostThreadMessage()みたいなものを探しています。 #「プロセス間通信」というものは発見しましたが・・・ 何か方法はありますでしょうか? スレッド間のメッセージのやり取りの方法がない場合は代替案も教えて頂きたいです。 # セマフォを用いて共有メモリアクセスかな?と思っています。

  • ITomo
  • お礼率36% (7/19)

質問者が選んだベストアンサー

  • ベストアンサー
  • guccii
  • ベストアンサー率31% (14/44)
回答No.1

pthreadでは、排他や条件セマフォ等はありますが、メッセージ交換のAPIはありません。おそらく多くの人はプロセス間通信を用いているのではないでしょうか? ただし、posixのメッセージキューは、実装により1プロセスがオープンできる数が著しく(32個とか)制限されていますし、SystemVのメッセージもOSの初期設定値が著しく低い値が設定されていたりして、現代的なマルチスレッドの設計には向いていないかもしれません。また、UNIXは所有者プロセスがいなくなってもリソースが残ってしまいますので、正直使いづらいです。 プロセス内でのみのメッセージ交換なら、pthreadとSTLなどを組み合わせてキューをつくることも考えられます。軽量で高速なキューの実装が可能です。とりあえず実装することは難しくないのですが、デッドロック等に十分に注意して実装してください。共有メモリにおけば、プロセス間通信も可能でしょう。 もうひとつは、パイプもしくはソケットを用いる方法が考えられます。UNIXではこれが一般的だろうと思われます。UNIXドメインのソケットを用いればポートをバインドする必要もありません。ソケットをラップして、キューライクなインターフェースにすることも可能でしょう。ただし、UNIXドメインのソケットがWindowsにないので、ポーティング・ソース共有が少し面度くさくなります。 あとは、メッセージキューイング製品を用いることも選択肢としてはあります。コスト的に許されればの話ですが。オープンソースもなくはないですが、試してみたことはないです。 といったところでしょうか。 ちなみにWindowsもプロセス間/スレッド間で用いるメッセージキューがありませんね。代わりにウインドウメッセージキューを用いることもありますが、信頼性が低い(Win3.1のころは最悪でした)。ウインドウを持たないスレッドに必ずウインドウメッセージキューを作成するあたりも少し不満が残ります。名前付きでオープンできないですし。代わりにmailslotをラップしてキューを実装してりしていました。最近はMSMQという選択肢もありますが。javaでもconcurrentパッケージがJDKに入ったのは最近ですし、こっちはプロセス間通信ができません。 世の中ではメッセージ交換方式のプログラミングがなかなか普及しないみたいで、各プラットフォームでいつも悩まされます。

ITomo
質問者

お礼

詳しいご説明ありがとうございます。 今回、初めてLinuxを使用して開発することになりまして。。。 pthreadで色々検索したのですが、API一覧が載っているHPはなかなかありませんでした。 # 本日、一件発見しました。 今回作成したものはWindows上でも動かしたいと思っていますので、 キューを作成しようと思います。 >ちなみにWindowsもプロセス間/スレッド間で用いるメッセージキューがありませんね。 PostThreadMessage()はスレッドのメッセージキューにメッセージをポストすると思っているのですが、 私は何か勘違いをしていますでしょうか?

その他の回答 (4)

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.5

がるです。 まず > 他のプロセスとのやり取りはありません。 了解です。 以下、これを前提にしたお話を。 前述しましたが、プロセスは「常にメモリ空間が個々に独立」していて、一方でスレッドは「同一メモリ空間内に複数存在する」ものになります。 一応念のため。「メモリ空間が独立しているスレッド」は存在しません(逆はありえまして。Linuxの場合、スレッドは"同一メモリ空間を共有する複数のプロセス"として実装されているので、ある見方によっては"メモリ空間を共有するプロセスがある"といえなくもないです。かなり余談ですが)。 プロセスは「メモリ空間が独立している」ために、通常プロセス間での情報のやり取りは「無理」で、ゆえに、どうしてもやむを得ず「プロセス間通信」なるものを使わざるを得ない、という事情があります。 一方で、スレッドの場合「メモリ空間を共有」しているので、たとえば「グローバル変数」とかが「各スレッドで共有しているブツ」になるので、特になにかを用意しなくても基本的な通信は行えてしまいます。 # ってか、たとえばpthreadで実装する場合、pthread_mutexとかちゃんと使わないと「共有したくないのに共有しちゃう」、いわゆる thread unsafeなブツになります。 このあたりが「何かしらの仕組みが」ない、理由になります。 あとは…単純なやり取りなら「通信用のglobalな変数」を設定するか、もうちょっと複雑にやりとりをするなら、「通信用のglobalな変数」を基点に、#3さんのおっしゃってるようなリングバッファの実装とかそのあたりをなさるとよろしいのかなぁとおもいます。 ちと蛇足的な部分もあり恐縮ですが。何かの参考にでもなれば幸いです。

ITomo
質問者

お礼

すぐにお礼ができず、申し訳ありませんでした。 細かいご説明ありがとうございます。 基本的な事の再確認ができました。 # 曖昧な部分もありました。 ご参考にさせて頂き、実装してみようと思います。

  • guccii
  • ベストアンサー率31% (14/44)
回答No.4

>>ちなみにWindowsもプロセス間/スレッド間で用>いるメッセージキューがありませんね。 >PostThreadMessage()はスレッドのメッセージキューにメッセージをポストすると思っているのですが、 >私は何か勘違いをしていますでしょうか? 説明不足でしたね。PostThreadMessageはウインドウメッセージキューを使用します。ウインドウメッセージキューは以前は信頼性が低く、メッセージ数が制限されていたことと、WM_TIMERなどのメッセージをOSがまとめたりもしますので、個人的になんとなく信頼がもてないということです。失っても構わないような通知レベルのメッセージならともかく、応答を必要とするデータを渡すのにウインドウメッセージキューを使用するのにはなんとなく抵抗があります。最近の環境ではおそらく問題ないとは思いますが、とはいえ、"post"は暗にメッセージロストすることを示唆しています。また、送信を確実に行おうとするためSendMessageをすると送信側にもウインドウメッセージキューが作られますから、スレッド数が多い場合には意識しないところで無駄なリソースを使ってしまっている可能性もあります。GUIの描画処理をマルチスレッド化する用途なら十分有用なのですが... また、GUI処理のウインドウメッセージと混ざってキューイングされることや、ほかのセマフォやイベントと複数待機できないのも少し不満です。 余談ですがOS/2にはメッセージキューがあったんですけどねぇ。

ITomo
質問者

お礼

すぐにお礼ができず、申し訳ありませんでした。 Windowsの詳しい説明までして頂き、大変参考になりました。 プログラミングしていましたが、中身をちゃんと理解して使用していませんでした。 基本的な事柄をもっと勉強して、開発をして行きたいと思います。 # 既存ソースを真似して作成したりすることが多かったです・・・ # 何かあったときに原因不明になってしまうかもしれませんね。 ありがとうございました。

  • moritan2
  • ベストアンサー率25% (168/670)
回答No.3

linuxの場合メモリを共有しないスレッドもあるのですが、メモリを共有するスレッドなら、リングバッファーでキューを作ってやるのが一番高速です。キュー2個で双方向の通信が出来ます。特別なAPIを使うわけではないので Windows でも linux でもなんでも動くし、セマフォとかクリティカルセクションのようなものも必要ありません。単純なだけに高速なので私はいつもこれを使っていますね。

ITomo
質問者

お礼

ご回答ありがとうございます。 スレッド間のやり取りは多くの人がやっていると思っていますので、 何かしらの仕組みが既にある(使える)かと思っていました。 自分で作るのはなんとかできるとは思いますが、 あるものを作ってもしょうがないですので・・・ キューは今まで作る機会がありませんでしたので、 勉強も兼ねて作ってみようと思います。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.2

がると申します。 一応念のため。「プロセスではなくてスレッド」ですよね? スレッドであると仮定すると。次に出てくるのは ・常に「同一プロセス内の各スレッド間での通信」 でしょうか?それとも ・「異なるプロセスの可能性のある各スレッド間での通信」 でしょうか? ここでまた回答が異なってきます。 大変に失礼ながら、ではあるのですが。たぶん、スレッドについてきちんと把握されていないのだろうと推測いたします。 スレッドとプロセスの違いを、特に「メモリ空間」の観点から一度調べてみると、色々と見えてくるのではないかと思います。 プロセスは「それぞれが独立している」事がメリットでもありデメリットでもあり。 スレッドは「同一メモリ空間内に共存している」事がメリットでもありデメリットでもあります。

ITomo
質問者

補足

「プロセスではなくてスレッド」です。 読みが深いですね。言葉が足らずすいません。 Linuxでスレッド間通信について調べていたら、 なぜか「プロセス間通信で・・・」という書き込みを見かけたもので、 質問に >#「プロセス間通信」というものは発見しましたが・・・ を書いたしだいです。 今回は1プロセスで5スレッドを生成し、この生成したスレッド間でメッセージのやり取りをしたいと思っていました。 他のプロセスとのやり取りはありません。

関連するQ&A

  • メッセージキューのスレッド間通信 

    linuxは全くの初心者なんですが、仕事でメッセージキューでスレッド間通信をするツールを作成するよう指示を受けたのですが全くわかりません。プロセス間通信をするツールは調べて何とかなったんですが… そもそもスレッド間通信ということがわからず困っていますので、ご教授願います。 簡単ものでいいのでツールについても教えていただけたら幸いです。

  • プロセス間でのメッセージキュー送信

    Linux初心者です。 あるプロセスが生成したメッセージキューへ、別のプロセスからメッセージキュー送信する場合、キューIDを指定する必要があります。 しかし、Linuxでは仮想メモリを使用しているため、共有メモリにアクセスできないはずで、異なるプロセス間でキューIDを共有する方法がわかりません。。 メッセージキューについて以下のサイトでサンプルプログラムが紹介されていますが、2つのプロセスが親子関係であるため、キューIDを共有できています。 http://linuxmag.sourceforge.jp/Japanese/March2003/article287.shtml そもそも、親子関係がないとプロセス間通信ができないのでしょうか? ご存知の方、よろしくお願いします。

  • 共有メモリでのデータ読み書きについて

    Linuxで共有メモリを複数プロセスで読み書きする場合について質問させて頂きます。 CPUは32ビットで、共有メモリ上の、int(32ビット)の領域を 複数のプロセスで読み書きする場合を想定した場合、 セマフォ等でロックした方が良いのでしょうか? または、CPUが1命令で読み書きすることが可能 (と思っていますが、違っていればご指摘お願い致します)なので、 セマフォ等のロックをかけなくても、問題はないものなのでしょうか? 割りと良くありそうな疑問だと思ったのですが、 ウェブで調べた限りでは該当する質問はありませんでしたので、 質問させて頂きました。 ご回答宜しくお願い致します。

  • LINUXのプロセス間通信について

    共有メモリを利用したプロセス間通信とメッセージを利用したプロセス間通信のメリットとデメリットを教えて下さい。

  • スレッド制御に関して

    C言語の初心者です。 現在、スレッドの勉強をしております。 最近、pthreadをなんとなく理解しつつありますが、 下記の2点に関して試行錯誤しております。 (1)スレッドを周期的に起動したい (2)時間によって起動したい (1)は、例えば30秒毎にスレッドを起動させたい等といった、周期スレッドの生成方法です。今考えているのは、スレッドを生成後、スレッド生成元で30秒間sleepして、2回目のスレッドを起動…。といったイメージを考えております。 (2)に関しても同様で、例えば12時00分00秒にスレッドを生成したいというパターンで、スレッド生成元にて、時間を取得して、その時間が12時00分00秒であればスレッド生成を行うといったイメージを考えております。 上記2案とも初心者なりに考えた案なのですが、他によい案はありませんでしょうか? ご教授頂けますようよろしくお願いいたします。

  • linux 共有オブジェクトの thread-safety

    自作の Windows dll を linux に移植しようとしています。 gcc で so を作ります。 dll は thread-safe にしてあります。その dll の関数を呼び出したすべてのスレッドに、それぞれ固有のメモリ領域を割り当てます。そして、あるスレッドが終了したら、そのスレッドに割り当てられた領域を解放することができるように、「そのスレッドが終了するのを待つスレッド」を作って待機させるようにしました。これで意図どおり動作しています。 ところが、このライブラリを linux に移植しようと、簡単なコードを書いて調べてみたところ、pthread_join() は親スレッドが子スレッドの終了を待つ場合にしか使えないことがわかりました。上の「そのスレッドが終了するのを待つスレッド」を作る、という方法が使えません。 linux で任意のスレッドの終了を知る方法はないでしょうか? あるいは、スレッド固有の領域を管理するもっと良い方法はあるでしょうか? それとも、linux で thread-safety なんか考える必要は無いのでしょうか?

  • linuxにてプロセス間通信をメッセージキューに行いたいのですが、

    linuxにてプロセス間通信をメッセージキューに行いたいのですが、 ある条件のときにキューに溜まったメッセージを削除したい場合はどのようにしたらいいでしょうか?

  • スレッドの意味

    マルチスレッドについて良い資料が見当たらず、教えて下さい。 OSにおけるマルチスレッドと言うと、同一プロセス内でメモリ空間を 共有して独立に動く一連の手続き、と捉えています。(シングルCPU シングルコアだとOSで時分割によって作られた仮想的な並列計算) Javaのようなマルチスレッドのプログラミング言語では「一つの プログラムから作られた二つの一連の手続き」と言うイメージが あります。※裏側の動作ではOSに依頼してJavaのプロセス内で OSのスレッドを生成して処理を渡しているだけ?と思っています。 CPUコアの内部で説明される「マルチスレッド」と言うのは、 どのようなレベルのスレッド(何が並列処理?何処まで並列?) なのでしょうか。

  • c# スレッド間でのデータの共有

    C#でメインプロセスと生成されたスレッド間でデータの共有をさせたいのですがどのようにすればいいのでしょうか。ご教授お願い致します。 ・メインプロセス(A) ・Aから生成されたスレッド(B) 例えば、AとBで変数の値をそれぞれ読み書きさせたい場合 どのようにすればよいのでしょうか。 class TEST { public int flag; // メインプロセス(A) public static void Main() { Thread t = new Thread(new ThreadStart(abc)); t.IsBackground = true; t.Start(); while(ture) { Thread.Sleep(10); Console.WriteLine("A:{0}",flag); } } // Aから生成されたスレッド(B) public void abc() { Console.WriteLine("B:{0}",flag); flag++; } }

  • プロセスとスレッドの違いについて(Cプログラミングの観点から)

    プロセスとスレッドの違いがしっくりきません。 <プロセス> (1)プログラムの実行単位。Windows や Linux などの汎用 OS 上のアプリケーションは一般にプロセスとして動作している。プロセスは1つ以上のスレッドと、ファイル、ヒープメモリなどのリソースで構成される (2)起動や切り替えのオーバーヘッドが大きい <スレッド> (1)同一プロセス内の複数スレッドを同一メモリ空間上で実行でき、メモリ消費量などが軽減できる。 (2)マルチスレッド処理のプログラミングにおいては、同じデータを複数のスレッドが同時に書き換えることによる不整合に注意し、排他制御を行う必要がある。 等はwiki等調べて理解しています。 何が疑問なのかと申し上げますと、具体的にプログラミングする際に (1)マルチプロセスとマルチスレッド方式では、ソースにどのような違いが出てくるか (2)マルチプロセスとマルチスレッド方式では実行時間がどれだけ変化するか がわからないのです。お仕事で並列処理等について担当されている方などおられましたら、お手数ですがご教授ください。 なお、わかりやすい書籍、webサイト等ありましたらそれも併せて教えていただけると助かります。よろしくお願いします。ちなみに、環境はWindowsXP,VisualC++ExpressEdition2005を使っていますので、UNIXよりはWindowsかつCで動くプログラム例で教えていただけると大変助かります。しかし、当方Javaも多少であれば組めますのでJavaでも構いません。 何卒、よろしくお願い致します。