QThread怪异的行为 [英] QThread weird behaviour
问题描述
我有一个运行某些代码的QThread,我希望它能够很好地退出并进行一些清理,因此代码如下:
I have a QThread running some code and I wanted it to do exit nicely and do some cleanings so the code goes as:
class testDevice : public QThread
{
Q_OBJECT
... // some definitions
protected:
void run(void);
private:
hid_device *handle;
bool abort;
public:
~testDevice(void);
};
testdevice.cpp
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
返回,然后析构函数继续
The behaviour I was expecting was run()
to be called and when ~testDevice()
destructor is called abort
is set to true
and wait
blocks the destructor, and run
returns and then the destructor continues.
发生的事情是,调用了run()
,当我关闭应用程序时,调用了析构函数~testDevice()
,并且将abort
设置为true
,并且wait()
返回并且析构函数完成了……但是run()
继续运行,并且在project.exe中的0x71241a95处出现未处理的异常:0xC0000005:访问冲突....我将其作为VS2010调试程序运行,如果我始终放置断点,则会得到此提示,但没有断点只是偶尔得到这个...任何线索吗?
What is happening is that run()
is called and when I close the application the destructors ~testDevice()
is called and abort
is set to true
and wait()
returns and the destructor finishes...BUT then run()
keeps running and I get Unhandled exception at 0x71241a95 in project.exe: 0xC0000005: Access violation.....I am running this as VS2010 debug, if I place breakpoints I get this all the time, but with no breakpoints I just got this once in a while...any clues?
奇怪的是,当我在abort = true;
中放置一个断点时,有时第一个击中的断点带有一个小的蓝色!".标志,并且第二次击中是常规的全红色标志.在emit deviceConnected(_connected);
处的断点也会发生同样的情况,但这也是随机的……我不知道这是什么'!'意味着...所有这些都可能是调试问题吗?
Something weird is that when I place a breakpoint in abort = true;
sometimes the first breakpoint that hits in there has a small blue '!' sign, and the second time it hits is a regular all red one. The same happens for the breakpoint at emit deviceConnected(_connected);
but this is kinda random as well...I dont know what this '!' means...could all of this be a debug problem?
我的普遍怀疑是HIDAPI在单独的线程中运行,当有人调用hid_exit();
时可能有其自身的错误,也许hid_read();
继续运行,并且由于hid_quit();
被调用,所以hid_read();
释放了一些指针并且没有结束...只是一个疯狂的镜头,并确认这一点,我需要HIDAPI的一些开发人员提出建议并说些什么...我希望他们读到此
My general suspicion is that HIDAPI is running in a separate thread and it has its own bugs when someone call hid_exit();
maybe hid_read();
continues to run and since hid_quit();
was called, hid_read();
looses some pointers and doesnt close...just a wild shot and to confirm this I need some developer at the HIDAPI to come foward and say something...I hope they read this
推荐答案
您似乎正在以自定义方式使用QThread
,而不是通常的start()
和quit()
执行.最好的办法是,在理想的情况下,如果可以使用quit()
重构代码以退出QThread
,因为这将更接近此QObject子类的信号/插槽机制.
You seem to be using QThread
in a custom way rather than the usual start()
and quit()
execution. The best would be that in an ideal world if you could refactor your code using quit()
for quiting a QThread
since that would be closer to the signal/slot mechanism of this QObject subclass.
但是,我同意这并不总是可能的.根据您提供的几行内容,我仍然无法告诉您,在这种情况下这是有道理的,但至少我会鼓励您考虑一下.
However, I agree that it is not always possible. I cannot yet tell you based on your few lines you provided that it would make sense in this particular case, but at least I would encourage you to think about it.
此外,您可以使用QWaitCondition
等待事件发生,而不是进行低级或自定义wait()
调用.
Also, you could possibly use the QWaitCondition
for waiting for something to happen rather than low-level or/and custom wait()
calls.
如果要解决当前面临的问题,如果当前的问题是编译器优化布尔值(例如将其放入缓存),则可以尝试使用 QAtomicInt 选项.这样可以确保编译器无法优化读写操作.
As for quickly working around the issue you are facing if the issue at hand is compiler optimization of a boolean value like putting it into the cache, you could try having making it atomic by using the std::atomic (C++11) or QAtomicInt option. This will make sure that the compiler cannot optimize the reads and writes out.
您将使用std typedef编写如下内容:
You would write something like this with the std typedef:
std::atomic_bool abort;
如果需要支持C ++-11之前的编译器以及Qt 4,则可以使用Qt类,如下所示:
If you need to support pre C++-11 compilers as well as Qt 4, you would use the Qt class like this:
QAtomicInt abort;
这篇关于QThread怪异的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!