C++ GTK 线程.我做得对吗
C++ Gtk threading. Am I doing it right?
我有一个gtkmm应用程序,我正在尝试将一些长时间运行的任务放入单独的线程中,这样它们就不会锁定GUI。这是我设计所基于的教程:
http://www.velvetcache.org/2008/09/30/gtkmmglibmm-thread-example
我使用 Glib::D ispatcher 信号在工作完成或需要更新某些内容时通知 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会不会有问题?那么这样做是否安全,那么只要我确定变量仅由单个线程修改,还是有更好的方法?
您有竞争条件。 即使您的 gui 线程不修改thread_message
,允许 GUI 线程在另一个线程修改它时读取它也不会给您带来长期的幸福。这是因为 std::string 本身不受多个线程访问它的保护,并且具有多个内部字段。 如果一个线程正在修改其内部字段之一,而另一个线程正在读取它们,则从第二个线程的角度来看,内部状态将不一致。
您可以在 GUI 类中使用互斥锁来保护对可能被另一个线程访问的变量的访问。 锁定和解锁 get/set 例程中的互斥锁,并将这些例程用于所有其他访问,以确保一次只有一个线程可以访问或修改变量。
通常,互斥体的使用不足以实现所需的行为。同一个工作线程(或另一个工作线程,如果有的话)可能想要发送另一条消息,而第一条消息尚未由主线程处理。这就是为什么除了互斥锁之外,您还应该使用消息队列(例如std::deque<std::string>
类的对象)而不是仅仅使用std::string Some_GUI_class::thread_message
变量来避免这种消息丢失。
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 异常属于C++中的线程还是进程
- C++中的线程安全删除
- C++使用params创建线程函数会导致转换错误
- 类与私有变量的其他类之间的线程安全性
- CoInitialize()在单独的线程上崩溃而不返回
- c++中的线程池
- 线程之间的布尔停止信号
- 为什么std::async使用同一个线程运行函数
- C++ GTK 线程.我做得对吗
- 在多线程应用程序中更新GTK接口的最佳方法是什么?
- GTK+接口应该在单独的线程中运行吗?