私はgtkmmアプリケーションを持っていて、GUIをロックしないように、長時間実行されるタスクを別々のスレッドに入れようとしています。これが私のデザインのベースとなったチュートリアルです:
http://www.velvetcache.org/2008/09/30/gtkmmglibmm-thread-example
Glib :: Dispatcherシグナルを使用して、作業が完了したとき、または何かを更新する必要があるときにGUIスレッドに通知しますが、ワーカースレッドとGUIスレッドの間でデータを渡す方法がわかりません。これまで、ワーカーを作成するクラスへのポインターをワーカーに渡してから、クラスのパブリックメンバーを変更してきましたが、それを行うのが最も適切ではないことがわかりました。次に例を示します。
class Some_GUI_class
{
public:
std::string thread_message;
private:
Worker_class* worker;
void start_worker()
{
if (worker != NULL) return;
worker = new Worker_class(this);
worker->sig_message.connect(sigc::mem_fun(*this, &Some_GUI_class::display_message_from_thread);
worker.start();
}
void display_message_from_thread()
{
some_label->set_text(thread_message);
}
}
class Worker_class
{
public:
Worker_class(Some_GUI_class* gui_class) : gui_class(gui_class)
{}
void start()
{
thread = Glib::Thread::create(sigc::mem_fun(*this, &Worker_class::run), true);
}
Glib::Dispather sig_message;
protected:
Glib::Thread* thread;
Glib::Mutex mutex;
Some_GUI_class* gui_class;
void run()
{
// ...
gui_class->thread_message = "Message from a thread!";
sig_message();
}
}
これは本質的には機能しますが、GUIスレッドが同時にthread_messageを変更したい場合は、問題が発生するのではないでしょうか。変数が単一のスレッドによってのみ変更されると確信している限り、このように行うのは安全ですか、それともより良い方法がありますか?