How can i protect function that is running inside QThread , so it will invoked only after it finished its work ?



  • hello ,
    im invoking QThread and inside its run methods i have timer that invoking function that preforme some heavy actions that takes time
    usiily more then the interval that trigger the timer ( but not allways ) .
    what i need is to protect this method so only it can be invoked only if it done its job :
    here is the code :
    @NotificationThread::NotificationThread(QObject *parent)
    :QThread(parent),
    bWorking(false),
    m_timerInterval(0)
    {

    }

    NotificationThread::~NotificationThread()
    {
    ;
    }

    void NotificationThread::fire()
    {

    if(!bWorking)
    {
    m_mutex.lock(); // <-- this is not protection the GetUpdateTime method from invoking over and over

    bWorking = true;
    
    int size = groupsMarkedForUpdate.size();
    if(MyApp::getInstance()->GetUpdateTime(batchVectorResult))
    
    {
     bWorking = false;
     emit UpdateNotifications();
     
     
    }
    

    m_mutex.unlock();
    }

    }

    void NotificationThread::run()
    {

    m_NotificationTimer = new QTimer();
    connect(m_NotificationTimer, SIGNAL(timeout()),
    this,SLOT(fire(),Qt::DirectConnection));

      int interval = val.toInt();
    

    m_NotificationTimer->setInterval(3000);
    m_NotificationTimer->start();

      QThread::exec&#40;&#41;;
    

    }

    // this method invoked from the main class
    void NotificationThread::Execute(const QStringList batchReqList)
    {

    m_batchReqList = batchReqList;
    start();
    }@



  • The answer depends on whether you want the GetUpdateTime() calls to "queue up" if a previous call is still running or whether you just want to discard the call until the next interval fires.

    For the former: Use an atomic integer to store how many calls are "queued up". If the count is 0 then the call is successful. If it's > 0 increment it by one. Wrap the function's code in "while(count > 0)" and decrement at then end. The problem is the test has to be "transactional" because this "bug" could occur: T1 - is count > 0? yes it is 1, T2 - finished call. decrement count. count = 0. exit while loop, T1 - increment count. Thread 2 can decrement between Thread 1's test and set causing the function to exit. So you will need an atomic test-then-increment which I don't think is available without using a lock. http://doc.qt.nokia.com/qq/qq14-threading.html#theatomicoperations

    For the latter: You can either have an atomic boolean as a flag for whether the function is running or you can have a QMutex as a flag and use tryLock() to just ignore the call if the lock attempt fails.



  • i tried to read your answer but i had difficult to understand it



  • What reactive wanted to say is:
    You have to options, when the timer fires and your function is still busy:

    You remember that the timer has fired and try to call GetUpdateTime, once it's available again, or

    You just discard it and wait for the timer to fire again

    Depending on what you want, we can help you with the code for either of those options.



  • found the solution based on the examples in Qt directory , thanks


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.