C++ C++;Gtk螺纹。我做得对吗?
我有一个gtkmm应用程序,我试图将一些长时间运行的任务放在单独的线程中,这样它们就不会锁定GUI。以下是我的设计基于的教程: 我使用Glib::Dispatcher信号在工作完成或需要更新某些内容时通知GUI线程,但是我不确定如何在工作线程和GUI线程之间传递数据。到目前为止,我一直在向创建worker的类传递一个指针,然后修改该类的公共成员,但有些事情告诉我这样做不是最正确的。下面是一个例子:C++ C++;Gtk螺纹。我做得对吗?,c++,multithreading,glib,gtkmm,C++,Multithreading,Glib,Gtkmm,我有一个gtkmm应用程序,我试图将一些长时间运行的任务放在单独的线程中,这样它们就不会锁定GUI。以下是我的设计基于的教程: 我使用Glib::Dispatcher信号在工作完成或需要更新某些内容时通知GUI线程,但是我不确定如何在工作线程和GUI线程之间传递数据。到目前为止,我一直在向创建worker的类传递一个指针,然后修改该类的公共成员,但有些事情告诉我这样做不是最正确的。下面是一个例子: class Some_GUI_class { public: std::string t
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_消息,那么会有问题吗?这样做安全吗?只要我确定变量仅由单个线程修改,还是有更好的方法?您有一个竞争条件。即使您的gui线程没有修改
thread\u消息
,允许gui线程在另一个线程修改它时读取它也不会给您带来长期的快乐。这是因为std::string本身不受多线程访问的保护,并且具有多个内部字段。如果一个线程正在修改其一个内部字段,而另一个线程正在读取这些字段,那么从第二个线程的角度来看,内部状态将不一致
您可以在GUI类中使用互斥体来保护对其他线程可能访问的变量的访问。在get/set例程中锁定和解锁互斥锁,并将这些例程用于所有其他访问,以确保一次只有一个线程访问或修改变量 通常,互斥体的使用不足以实现所需的行为。当主线程尚未处理第一条消息时,同一个工作线程(如果有的话,也可以是另一条)可能想要发送另一条消息。这就是为什么除了互斥外,还应该使用消息队列(例如
std::dequestd::string
class的对象)不要只使用std::string一些\u GUI\u class::thread\u message
变量来避免这种消息丢失。我不是gtk专家,但据我所知,UI有一个消息循环,所以您需要在主线程中捕获这些消息,然后作为事件触发,这很棘手。@jakubobza Glib::Dispatcher就是这么做的。谢谢。这是有道理的。您能否提供一个简单的代码示例来说明如何实现它。我是否只需要添加互斥体类成员并调用Glib::mutex::Lock(互斥体);在get/set方法的顶部?基本上就是这样。需要明确的是,由于您是在保护数据成员,所以互斥对象应该是数据成员(而不是类(静态)成员)。