2014年1月6日月曜日

C言語で,Gtk+とgthread

gtk+2.0とgthreadでマルチスレッドのプログラムを作りたいのですが,意外と情報が少なく困っています.

たとえばGUIで測定プログラムを動かしていて,途中で電流値などのパラメータを変えたいと思っても,マルチスレッド化しなければ普通はループが終るまで変数の変更を許してくれません.

そこで,測定ルーチンは別のスレッドで無限ループにしておいて,メインのスレッドではボタンをクリックしたりentryウィジェットで数値を入力したりしてループ条件やパラメータを変更する,と言う風にスレッドを分けることが必要になります.

具体的には,メイン関数の中で
GThread* thread;

g_thread_init(NULL);
gdk_threads_init();

と初期化した後,
thread = g_thread_create ( thread_func, (gpointer)label3, FALSE, &error );
という風にしてthread_funcを別スレッドで立ち上げる.ここでlabel3を引数として与えているのは,thread_funcのなかでlabel3のテキストをリアルタイムで書き換えているからです.

thread_funcはgpointer型にする必要があるらしく,実際の中身は
static gpointer thread_func ( gpointer data )
{
  while( TRUE ){
  g_usleep(500000);
   
  if(start_or_stop != 0){
  .
  .
  .
  gtk_label_set_text(GTK_LABEL (data), buf);
  }
  
  }
みたいな感じにしています.

ここで,start_or_stopはintで宣言していて,0のときは何も実行されない.
メイン関数のボタンをクリックするとstart_or_stopが0になったり1になったりする,という仕組みです.
gboolean型でも良かったのかもしれないのですが,caseで処理を分けるかもしれないことを考えて,intにしておきました.

実際はこんな感じ



これは実際に測定しているわけではなく,0.5秒おきにスピン1/2三角格子ハイゼンベルグ反強磁性体の帯磁率を1ケルビンおきに計算してプロットするというプログラムを測定ルーチンのかわりに入れています.

0 件のコメント:

コメントを投稿