How to safely stop the running thread at the request of the user?

I have a scenario where I have to interrupt a stream while the stream is working in accordance with the user action in the GUI. I am using Qt 4.5.2 for Windows. One way to do this:

class MyThread : public QThread
{
    QMutex mutex;
    bool stop;

    public:
        MyThread() : stop(false) {}

        void requestStop()
        {
            QMutexLocker(&mutex);
            stop = true;
        }

        void run()
        {
            while(counter1--)
            {
                QMutexLocker(&mutex);
                if (stop) return;

                while(counter2--)
                {
                }
            }
        }
};

Please note that the code above is minimal. The start function may take up to 20 seconds to complete, so I want to avoid locking and unlocking the variable mutexin a loop. Is there any other way faster than this method.

Thanks in advance.

+3
source share
5 answers

-, , , if (stop), , , . , requestStop() , .

, , "". "volatile" ( , V++) /, , , requestStop() . .

class MyThread : public QThread
{
    volatile bool stop;

    public:
        MyThread() : stop(false) {}

        void requestStop()
        {
            stop = true;
        }

        void run()
        {
            while(counter1--)
            {
                if (stop) return;

                while(counter2--)
                {
                }
            }
        }
};
+4

, ?

while(counter1--) {
    {
      QMutexLocker(&mutex);
      if (stop) return;
    } // End locking scope : we won't read it anymore until next time
    while(counter2--)
...   
+8

, , . stop. ( , ). QAtomicInt.

0

, , , ( , Qt - ), , , .

, ( , - ), , , . , 20 , , , . , , - , . , -, .

Qt, , , ( Win32), QSemaphore :

class MyThread : public QThread
{
    QSemaphore stopFlag;

    public:
        MyThread() : stopFlag( 1) {}

        void requestStop()
        {
            stopFlag.tryAcquire();  // decrement the flag (if it hasn't been already)
        }

        void run()
        {
            while(counter1--)
            {
                if (!stopFlag.available()) return;

                while(counter2--)
                {
                }
            }
        }
};
0

. .

Otherwise, you should use this approach. If you want the workflow to complete within a certain interval of t seconds, it needs to check the completion event at least once every few seconds.

0
source

Source: https://habr.com/ru/post/1722003/


All Articles