GTK関係をチェックイン

先日作成した、GTK関係のサポートライブラリ、およびサンプルプログラムのファイルを整理して(あとちょっとデバッグして)チェックイン。最新tarファイルはこちらから:http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/pards/pards.tar.gz?view=tar

サンプルはこちら:http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/pards/pards/gtk/gtksample.cc?rev=1.1&view=markup
ちょっと説明すると、

  SyncQueue<Callback*> *c = new SyncQueue<Callback*>(1);
  gtkhelper_init(c);

  Merger<Callback*> *m = new Merger<Callback*>(c,2);
  SPAWN(worker(1,m));
  SPAWN(worker(2,m));

のように、まずSyncQueue型の変数を作成し(SyncList型でもよい)、そのポインタをgtkhelper_init()に渡します。これで、ライブラリによって(パイプを使った)コールバックが設定され、Callback*型変数のrun()メソッドが、値がQueue(List)に入るたびに呼ばれます。

その下はMergerを使って、workerとなるプロセスが、当該Queue(List)に値を入れていく処理を記述しています。

workerの定義は以下の通り:

class MyCallback : public Callback
{
public:
  int val;
  int id;
  void run(){
    char str[1000];
    sprintf(str,"Message from Process %d, val = %d\n",id,val);
    strcpy(currentpos,str);
    currentpos += strlen(str);
    gtk_label_set_text(GTK_LABEL(label),labelchars);
  }
};

void worker(int id, Merger<Callback*> *c)
{  
  for(int i = 0; i < 5; i++){
    sleep(1);
    MyCallback* val = new MyCallback;
    val->id = id;
    val->val = i;
    c->put(val);
  }
  c->release();
}

細かい部分は省略・変更しています。
ここでは自分で使うCallbackをMyCallbackとして定義しています。リストに値を入れると、ここで再定義されたrun()が呼ばれます。ここでは、文字列を更新して、ラベルに表示される内容を変更しています。
workerはMyCallbackにrun()を実行するのに必要な変数をセットして、リストに値を入れています(Mergerを使っているので、putで値が入ります)。
workerの実行には時間がかかるかも知れませんが(sleepが入っている)、それはGUIの他の処理に影響しません。

とまぁ、比較的簡単に、並行処理が実現できます。

まぁ確かにsocketとか使うだけなら、標準機能のファイルディスクリプタ待ちや、スレッドを使うだけでできる、という話もあるかもしれないけど、この機能を使ったほうが見通しが良くなることもあると思う。(スレッド使うのは結構大変なんじゃないかなぁ。ロック・アンロックによる保護が必ず必要だろうし。)

マニュアルを更新したらリリースするかなぁ。