たとえば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 件のコメント:
コメントを投稿