问题
I have a QThread running some code and I wanted it to do exit nicely and do some cleanings so the code goes as:
testdevice.h
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
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 runreturns and then the destructor continues.
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?
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?
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
回答1:
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.
Also, you could possibly use the QWaitCondition for waiting for something to happen rather than low-level or/and custom wait() calls.
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.
You would write something like this with the std typedef:
std::atomic_bool abort;
If you need to support pre C++-11 compilers as well as Qt 4, you would use the Qt class like this:
QAtomicInt abort;
来源:https://stackoverflow.com/questions/20808217/qthread-weird-behaviour