GUIへの応用
PARDSの並行処理サポート機能を使って、テストとしてごく簡単なGTK+プログラムを書いてみた。ポイントは、SPAWNしたプロセスの出力をUIにどう反映するかの部分。SPAWNしたプロセスが例えばSyncListに出力を出していくとして、受け取り側でread()を実行すると、プロセスがブロックしてしまう。そうすると、GUIプログラムとしての他の処理(例えばボタンを押すと何かの反応をするとか)も処理されなくなってしまう。
これを解決するため、ちょっとしたヘルパーライブラリを作成した。
- GTK+のファイルディスクリプタ待ち機能を使う
- SyncListの内容を見て、値が決まるとパイプに書き込むプロセスを作成する
- パイプに書き込まれると、GUI側でSyncListの値を読み込み(書き込まれているのでブロックしない)、書き込まれた内容に対応する処理を行う
という寸法。
中でやっていることはややこしいけど、ユーザは接続用の初期化関数を呼び出すだけ。初期化関数の中で、対応するSyncListの最初のセルへのポインタを渡す。
このSyncListはSyncList
ユーザはCallbackクラスから継承して、自分のコールバック用クラスを作成する。run()を再定義すると、再定義されたrunがGUI側で呼び出される。run()の中で必要なデータはそのクラスのメンバ変数として定義する。
Callbackクラスはnewを使って確保すると、共有メモリ上に置かれるので、GUI側でもデータにアクセスできる。
プログラムの様子は添付した画像の通り。複数のプロセスからの入力を表示しつつ(ここにはMergerを使っている)、ボタンからの入力を受けつけている。
余談だが、作成中デバッグではまってしまった。printfデバッグしていたのだが、(マルチプロセスなので)どこでセグメンテーションフォールトが起こっているのか分らなくて…
今から考えると、gdbでプロセスをフォークする部分をひっかけて、新しく生成したプロセスに別のgdbからアタッチすれば良かったか? 次は試してみよう。