The following thread synchronization tool is required:

  • Can be created in any thread.
  • When the wait method was called, it would suspend the current thread if the take method was called in any thread earlier.
  • If you call the wait method, you would not do anything if the release method was previously called on any thread.
  • A take and release call counter is not required.

The Qt documentation saw the following thread synchronization tools: QMutex , QSemaphore , QWaitCondition . Unsuitable. In QWaitCondition every time you need to call the wake method, otherwise when you call wait program will continue execution only once, but it is necessary that the thread continue execution until the method that is not there is called ...

  • And what does Mutex not fit? Replace wait with take + release. - VladD
  • and what problem are you trying to solve? Make it possible to pause the stream? You can wrap QWaitCondition in your own wrapper. - KoVadim
  • @KoVadim, you need to really pause the thread, but you can't do it in an arbitrary place, only where the wait method is called. - maestro
  • @VladD, do you mean that the target thread blocks the mutex and immediately releases it? I did not think about it. - maestro
  • @maestro: Yeah, sort of, do you need exactly this according to the description? - VladD

1 answer 1

The mutex lock / unlock option was not immediately successful, because in Qt you cannot call the unlock method several times in a row. Therefore, we had to enter the state flag. All together wrapped in this class:

semaphorebinary.h:

 #ifndef SEMAPHOREBINARY_H #define SEMAPHOREBINARY_H #include <QObject> #include <QMutex> class SemaphoreBinary : public QObject { Q_OBJECT public: explicit SemaphoreBinary(QObject *parent = 0); explicit SemaphoreBinary(bool taken, QObject *parent = 0); void wait(); void take(); void release(); signals: public slots: private: QMutex suspendMutex; QMutex stoppedMutex; bool stopped; }; #endif // SEMAPHOREBINARY_H 

semaphorebinary.cpp:

 #include "semaphorebinary.h" SemaphoreBinary::SemaphoreBinary(QObject *parent) : QObject(parent), stopped(false) { } SemaphoreBinary::SemaphoreBinary(bool taken, QObject *parent) : QObject(parent), stopped(taken) { } void SemaphoreBinary::wait() { stoppedMutex.lock(); if (stopped) { stoppedMutex.unlock(); suspendMutex.lock(); suspendMutex.unlock(); return; } stoppedMutex.unlock(); } void SemaphoreBinary::take() { stoppedMutex.lock(); if (!stopped) { stopped = true; stoppedMutex.unlock(); suspendMutex.lock(); return; } stoppedMutex.unlock(); } void SemaphoreBinary::release() { stoppedMutex.lock(); if (stopped) { stopped = false; stoppedMutex.unlock(); suspendMutex.unlock(); return; } stoppedMutex.unlock(); }