【发布时间】:2019-06-09 17:05:35
【问题描述】:
我的应用程序中有 2 个线程 - 一个是 UI,第二个是更新一些数据。第二个线程的类继承wxThread类,并有一些变量,特别是Worker *worker。
class Worker {
public:
virtual void work() {}
};
class WorkerThread : public wxThread {
public:
bool isRunning = true;
Worker *worker;
virtual ExitCode Entry() {
while (isRunning) {
if (worker == nullptr) continue;
worker->work();
usleep(UPDATE_DELAY_USEC);
}
std::cout << "Done\n";
return 0;
}
};
如果我将 worker 的值从第一个线程更改为 nullptr,应用程序将继续正常工作。例如,如果我将值更改为 new Worker() 或与原来相同的值,应用程序将直接退出。没有任何错误打印到控制台。
我在wxNotebook事件中更改了这个指针:
void onPageChanged(wxBookCtrlEvent &event) {
switch (event.GetOldSelection()) {
case MNP_PROCESSES:
workerThread->worker = nullptr;
break;
}
switch (event.GetSelection()) {
case MNP_PROCESSES:
workerThread->worker = &processes->worker;
break;
}
}
整个奇怪的事情是,如果我将Worker *worker 带到全局范围,那么一切都会正常工作,没有任何错误。
Worker *worker;
class WorkerThread : public wxThread {
...
是什么原因?
【问题讨论】:
-
目前还不清楚“工作正常”和“简单退出”之间的关系。但它是错误的,你不能在没有同步的情况下更改变量。例如,如果您将值更新为 nullptr 并且线程恰好在 if 语句之后使用它,那么它将爆炸。不是唯一的问题,它的波动性不是很大,它只会继续使用旧值。除非你把它变成全球性的。需要同步。
-
wxWidgets 要求所有 GUI 操作都在一个线程中执行。 docs.wxwidgets.org/3.0/overview_thread.html
-
@stark,所有GUI操作都在一个线程中传递
-
@HansPassant,您说:“例如,如果您将值更新为 nullptr,并且线程恰好在 if 语句之后使用它,那么它将爆炸”,是的,我明白,nullptr用于示例
-
我能够使用 gdb 获得错误消息:
Thread 1 "main" received signal SIGSEGV, Segmentation fault. workerThread->worker = &processes->worker;
标签: c++ multithreading wxwidgets