QThread怪异的行为 [英] QThread weird behaviour

查看:121
本文介绍了QThread怪异的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个运行某些代码的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 runreturns 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.

如果要解决当前面临的问题,如果当前的问题是编译器优化布尔值(例如将其放入缓存),则可以尝试使用

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆