- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有弹出菜单的单线程 FLTK 应用程序,使用 Fluid 创建。我有一个子类 Fl_Gl_Window 并实现了一个 handle() 方法。 handle() 方法调用一个函数,该函数在右键单击时创建一个弹出窗口。我对其中一个菜单项进行了长时间的操作。我的应用程序为其他目的创建了第二个线程。我使用锁来保护我的主线程和第二个线程之间的一些关键部分。特别是, doLongOperation() 使用锁。
我的问题是我可以弹出菜单两次并运行 doLongOperation() 两次,然后它会自行死锁,挂起应用程序。 为什么第一个 doLongOperation() 不停止 GUI 并阻止我第二次启动 doLongOperation()?
我可以用一个用来禁用有问题的菜单项的标志来避免这个问题,但我想首先了解为什么它是可能的。
这是代码,当然是缩写的。希望我已经包含了所有相关的部分。
class MyClass {
void doLongOperation();
};
class MyApplication : public MyClass {
MyApplication();
void run();
void popup_menu();
};
void MyClass::doLongOperation()
{
this->enterCriticalSection();
// stuff
// EDIT
// @vladr I did leave out a relevant bit.
// Inside this critical section, I was calling Fl::check().
// That let the GUI handle a new popup and dispatch a new
// doLongOperation() which is what lead to deadlock.
// END EDIT
this->leaveCriticalSection();
}
MyApplication::MyApplication() : MyClass()
{
// ...
{ m_mainWindowPtr = new Fl_Double_Window(820, 935, "Title");
m_mainWindowPtr->callback((Fl_Callback*)cb_m_mainWindowPtr, (void*)(this));
{ m_wireFrameViewPtr = new DerivedFrom_Fl_Gl_Window(10, 40, 800, 560);
// ...
}
m_mainWindowPtr->end();
} // Fl_Double_Window* m_mainWindowPtr
m_wireFrameViewPtr->setInteractive();
m_mainWindowPtr->position(7,54);
m_mainWindowPtr->show(1, &(argv[0]));
Fl::wait();
}
void MyApplication::run() {
bool keepRunning = true;
while(keepRunning) {
m_wireFrameViewPtr->redraw();
m_wireFrameView2Ptr->redraw();
MyClass::Status result = this->runOneIteration();
switch(result) {
case DONE: keepRunning = false; break;
case NONE: Fl::wait(0.001); break;
case MORE: Fl::check(); break;
default: keepRunning = false;
}
}
void MyApplication::popup_menu() {
Fl_Menu_Item *rclick_menu;
int longOperationFlag = 0;
// To avoid the deadlock I can set the flag when I'm "busy".
//if (this->isBusy()) longOperationFlag = FL_MENU_INACTIVE;
Fl_Menu_Item single_rclick_menu[] = {
{ "Do long operation", 0, 0, 0, longOperationFlag },
// etc. ...
{ 0 }
};
// Define multiple_rclick_menu...
if (this->m_selectedLandmarks.size() == 1) rclick_menu = single_rclick_menu;
else rclick_menu = multiple_rclick_menu;
const Fl_Menu_Item *m = rclick_menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
if (!m) return;
if (strcmp(m->label(), "Do long operation") == 0) {
this->doLongOperation();
return;
}
// Etc.
}
最佳答案
确保您不是 调用Fl::wait(...)
来自多个线程。 我从您的代码中推断出 run()
是否正确?在自己的线程中执行?
第一次调用 Fl::wait()
,例如从主线程,将捕获并处理第一次右键单击(如预期的那样阻塞,而第一次调用 doLongOperation()
继续进行);同时,第二个线程调用例如Fl::wait(timeout)/Fl::check()
将继续刷新显示 -- 并将拦截(并服务)第二次右键单击,调用 handle()
(在第二个线程中)而第一个长时间操作仍在艰难中。这会出现死锁,尽管我希望 UI 会在两个长操作完成时恢复重绘(通过第二个线程)。
通过在 popup_menu()
中记录当前线程 ID 来验证上述内容.
您应该选择一个线程来调用 Fl::wait(...)
在一个循环中,你不应该阻塞那个循环 -- 将任何非模态或非 UI 任务生成为单独的线程。 IE。当popup_menu()
被调用,在自己的线程中启动长操作;如果 popup_menu()
在长操作线程仍在运行时触发(再次),或者将弹出菜单项标记为禁用(类似于您的解决方法),或者简单地向长操作线程发出信号以使用新参数重新启动。
关于deadlock - 为什么我会在单线程 FLTK 应用程序中死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3416010/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!