SetEvent不在qthread中释放WaitForSingleObject

时间:2015-09-09 06:30:02

标签: c++ qt winapi events qthread

我不熟悉winApi。我的要求是监视特定路径中目录的变化。所以我尝试了这样的代码。

#include <QObject>
#include <QThread>
#include <QReadWriteLock>
#include <QDebug>

#ifdef Q_OS_WIN
#include <windows.h>
#include <Winbase.h>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#endif // Q_OS_WIN

#ifdef Q_OS_LINUX
#include <unistd.h>
#endif // Q_OS_LINUX




class Worker : public QObject {
    Q_OBJECT

public:
    QReadWriteLock lock;
    bool running;
    LPCWSTR m_path;
    HANDLE myEvent;



public slots:
    void loop() {
        qDebug() << "entering the loop";
        bool _running;
        forever {

            lock.lockForRead();
            _running = running;
            lock.unlock();

            if (!_running) return;

            qDebug() << "loop iteration";

#ifdef Q_OS_WIN
            OVERLAPPED overlapped;
            memset(&overlapped, 0, sizeof(overlapped));
            overlapped.hEvent = myEvent;
            myEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
            DWORD dwWaitResult  = WaitForSingleObject(overlapped.hEvent, INFINITE);

            switch (dwWaitResult)
             {
            case WAIT_OBJECT_0:

                qDebug()<<"Success";
                break;

            case WAIT_FAILED:
                //break;
            case WAIT_ABANDONED:

                 qDebug()<<"nWait failed.";
                break;
            case WAIT_TIMEOUT:
//                consoleprintf(L"\r\nWait Timed out: %d", waitTime);
                qDebug()<<"nWait Timed out.";
                break;
            default:
                qDebug()<<"Something else";
                break;
            }


#endif // Q_OS_WIN

    }
    qDebug()<<"Closing the loop ends..";
}

void closeLoop()
{

    WINBOOL state = SetEvent(myEvent);
    CloseHandle(myEvent);
     qDebug()<<"Releasing the close loop:"<<state;
}

private:


    };

class DirControll {
public:
    DirControll(const QString &apath) : m_currentPath(apath)
    {
        LPCWSTR path ;
        path = reinterpret_cast<LPCWSTR>(m_currentPath.utf16());
        myWorker.m_path = path;
        myWorker.running = true;
        myWorker.connect(&myThread, SIGNAL(started()), &myWorker, SLOT(loop()));
        myWorker.moveToThread(&myThread);
        myThread.start();
    }
~Controller() {
    CloseController();

    //myThread.wait();
    //myThread.exit();
    //myThread.terminate();
}

void CloseDirControll()
{
    // Safely close threads
    myWorker.closeLoop();
    myWorker.lock.lockForWrite();
    myWorker.running = false;
    myWorker.lock.unlock();

    myThread.quit();
    qDebug()<<"the thread still runnign:"<<myThread.isRunning();
}

私人:     QThread myThread;     工人myWorker;     QString m_currentPath; };

但我无法在调用CloseDirControll()时关闭线程 - &gt; closeLoop()。WaitForSingleObject不会解除阻塞我的线程关闭。 SetEvent(myEvent)没有释放我的WaitForSingleObject,我没有关闭线程循环。

2 个答案:

答案 0 :(得分:1)

你可能错误输入了这3行。

overlapped.hEvent = myEvent;
myEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
DWORD dwWaitResult  = WaitForSingleObject(overlapped.hEvent, INFINITE);

您应该交换第2行和第1行。

答案 1 :(得分:1)

您错放了myEvent初始化:

OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(overlapped));

// Here you assign myEvent - which is not yet initialized
overlapped.hEvent = myEvent;

myEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Above line 'overlapped.hEvent = myEvent;' should be here

DWORD dwWaitResult  = WaitForSingleObject(overlapped.hEvent, INFINITE);