我有一个QThread运行一些代码,我希望它能很好地退出并进行一些清理,所以代码如下:
class testDevice : public QThread
{
Q_OBJECT
... // some definitions
protected:
void run(void);
private:
hid_device *handle;
bool abort;
public:
~testDevice(void);
};
testDevice::~testDevice(void)
{
mutex.lock();
abort = true;
mutex.unlock();
wait();
if (handle != NULL)
{
hid_close(handle);
}
hid_exit();
}
void testDevice::run(void)
{
while(true)
{
mutex.lock();
if(abort)
{
return;
}
mutex.unlock();
if (_connected)
{
//... more code
}
else // Case device is not connected
{
emit deviceConnected(_connected);// A breakpoint in here is not triggered after abort is true
handle = hid_open(TEST_VID, TEST_PID, NULL); // this is where VS2010 shows the error "Unhandled exception at 0x71241a95 in project.exe: 0xC0000005: Access violation."
//...code continues
我期望的行为是run()
被调用,当调用~testDevice()
析构函数时abort
设置为true
而wait
阻止析构函数,并且run
返回,然后析构函数继续。
正在发生的事情是run()
被调用,当我关闭应用程序时,调用析构函数~testDevice()
并将abort
设置为true
和wait()
返回并且析构函数完成...然后run()
继续运行,我在project.exe中的0x71241a95处得到未处理的异常:0xC0000005:访问冲突.....我运行这个作为VS2010调试,如果我放置断点我总是得到这个,但没有断点,我偶尔会得到这个...任何线索?
奇怪的是,当我在abort = true;
中放置一个断点时,有时会遇到第一个断点,那里有一个小的蓝色'!'标志,它第二次击中是一个常规的全红色。对于emit deviceConnected(_connected);
处的断点也是如此,但这也是随机的......我不知道这是什么'!'意味着...所有这些都可能是调试问题吗?
我一般怀疑HIDAPI是在一个单独的线程中运行的,当有人调用hid_exit();
hid_read();
可能hid_quit();
继续运行且调用hid_read();
时,它有自己的错误,{{ 1}}失去了一些指针并且没有关闭...只是一个疯狂的镜头,为了证实这一点,我需要HIDAPI的一些开发人员前来找一些东西...我希望他们读到这个
答案 0 :(得分:1)
您似乎以自定义方式使用QThread
,而不是通常的start()
和quit()
执行。如果你可以使用quit()
重构你的代码以退出QThread
,那么理想世界中最好的是,因为那将更接近这个QObject子类的信号/槽机制。
但是,我同意并非总是可行。我还不能根据你提供的几行来告诉你,在这种特殊情况下它会有意义,但至少我会鼓励你去考虑它。
此外,您可以使用QWaitCondition
等待某些事情发生,而不是低级别或/和自定义wait()
来电。
至于快速解决你遇到的问题,如果手头的问题是布尔值的编译器优化,比如将它放入缓存,你可以尝试使用std::atomic(C +)使其成为原子+11)或QAtomicInt选项。这将确保编译器无法优化读写操作。
您可以使用std typedef编写类似的内容:
std::atomic_bool abort;
如果您需要支持预编译C ++ - 11编译器以及Qt 4,您可以像这样使用Qt类:
QAtomicInt abort;