Destroying locked mutex ошибка

Given the following code:

#include <chrono>
#include <ctime>
#include <functional>
#include <iostream>
#include <thread>
#include <utility>

#include <QFuture>
#include <QMutex>
#include <QWaitCondition>
#include <QtConcurrent>

class Async
{
public:
    Async() = default;
    Async(const Async&) = delete;
    Async(Async&&) = delete;

    ~Async() = default; //{ m_mutex.unlock(); }

    Async& operator=(const Async&) = delete;
    Async& operator=(Async&&) = delete;

    template<typename t_result>
    QFuture<bool> operator()(
          std::function<t_result()>&& p_function,
          std::chrono::milliseconds p_timeout,
          t_result* p_result)
    {
        QtConcurrent::run([this, p_function, p_result]() {
            *p_result = p_function();
            std::cout << time(nullptr) << " waking" << std::endl;
            m_cond.wakeAll();
    });

    return QtConcurrent::run([this, p_timeout]() {
           std::cout << time(nullptr) << " starting to wait for "
                     << p_timeout.count() << " ms" << std::endl;
           m_mutex.lock();
           bool wait =
               m_cond.wait(&m_mutex, 
                           static_cast<unsigned 
                                       long>(p_timeout.count()));
           std::cout << time(nullptr)
                     << ", finished waiting = " 
                     << (wait ? "T" : "F") 
                     << std::endl;
           if (wait) {
               return false;
           }
           return true;
    });
  }

private:
    QMutex m_mutex;
    QWaitCondition m_cond;
};

int main()
{
  Async async;

  char letter = 'z';

  std::function<char()> f1 = []() -> char {
      std::this_thread::sleep_for(std::chrono::seconds(4));
      return 'a';
  };

  std::cout << "1: " << time(nullptr) << std::endl;
  QFuture<bool> result =
    async(std::move(f1), std::chrono::milliseconds(3999), 
          &letter);

  std::cout << "2: " << time(nullptr) << std::endl;

  std::this_thread::sleep_for(std::chrono::seconds(8));

  std::cout << "3: " << time(nullptr) << std::endl;

  if (result.result()) {
    std::cout << "timeout, letter = " << letter;
  } else {
    std::cout << "NO timeout, letter = " << letter;
  }
  std::cout << std::endl;

  return 0;
}

Finally… 8), when I run it, all the cout print what is expected, but I get a QMutex: destroying locked mutex at the end of the execution. Since I am getting the message finished waiting, the m_cond.wait is executed, therefore (I thought), m_mutex would be unlocked. But it does not seem so.

If I use ~Async() { m_mutex.unlock(); }, I do not get the message, but I do not think it should be done this way.

Could anyone, please, explain why the mutex is not being released?

Thanks a lot!

All QT5 applications do work. Forgot to mention that it’s KDE 5.7 from community repos. If it matters KDE Frameworks 5.24.0, Qt 5.7.0 (built with version 5.7.0). Recently Qt was version 5.6 maybe that matters too.

Here’s output of ~/.config/PBE/QOwnNotes.conf:

[General]
LastUpdateCheck=@DateTime(x10%x7fxf5x2x8exa3!)
PiwikClientId=
ShowSystemTray=false
SortingModeAlphabetically=false
allowDifferentNoteFileName=false
allowOnlyOneAppInstance=true
cryptoKey=
currentNoteFolderId=1
customNoteFileExtensionList=@Invalid()
darkMode=false
darkModeColors=false
defaultNoteFileExtension=md
demoNotesCreated=true
disableAutomaticUpdateDialog=true
externalEditorPath=
ignoreAllExternalModifications=false
interfaceLanguage=
mainSplitterSizes=@ByteArray(xffx1x5Ix1xex3x2xf0x3x80x1x1x1)
mainSplitterState-0-1-0-0=@ByteArray(xffx1x5x1]x4bx1x1x1)
mainSplitterState-0-1-1-0=@ByteArray(xffx1x5Ix1xex3x2xf0x3x80x1x1x1)
mainSplitterState-1-1-1-0=@ByteArray(xffx1x5xf5xfbx3x3xf7x1x97x1x1x1)
markdownHighlightingInterval=200
noteEditPaneEnabled=true
noteListSplitterState=@ByteArray(xffx1x2xd8xc0x1xffxffxffxffx1x2)
noteSaveIntervalTime=10
notesPath=
notifyAllExternalModifications=false
showStatusBar=true
tagFrameSplitterState=@ByteArray(xffx1x2xd8xd8x1xffxffxffxffx1x2)
tagsEnabled=false
verticalNoteFrameSplitterState=@ByteArray(xffx1x1x1x2)

[DistractionFreeMode]
editorWidthMode=1
isEnabled=false
mainSplitterSizes=@ByteArray(xffx1x5Ix1*x3x3%x3/x1x1x1)
menuBarGeometry=@ByteArray(x1xd9xd0xcbx2ax7fx1axffxffxffxffxffxffxffxffax80)
menuBarHeight=27
windowState=@ByteArray(xffxfdax80x3xa6x4x4bbxfcx1x2x6x16mx61inToolx42x61rx1xffxffxffxff"x66ormx61ttingToolx62x61rx1x1xa4xffxffxffxff insx65rtingToolx62x61rx1x2x18xffxffxffxff"x65nx63ryptionToolx62x61rx1x2x8cxffxffxffxffx1awinx64owToolx62x61rx1x3xffxffxffxffx16quitToolx62x61rx1x4x4xffxffxffxff)

[LogDialog]
showAtStartup=false

[MainWindow]
geometry="@ByteArray(x1xd9xd0xcbx2ax7fx4x1bxd7Hx6=x4Ox2ax80)"
mainToolBar.iconSize=22
menuBarGeometry=@ByteArray(x1xd9xd0xcbx2ax7fx1axffxffxffxffxffxffxffxffax80)
noteTextEdit.code.font="Droid Sans Mono,10,-1,5,50,0,0,0,0,0"
noteTextEdit.font="Droid Sans,10,-1,5,50,0,0,0,0,0"
noteTextView.code.font="Droid Sans Mono,10,-1,5,50,0,0,0,0,0"
noteTextView.font="Droid Sans,10,-1,5,50,0,0,0,0,0"
showRecentNoteFolderInMainArea=true
windowState=@ByteArray(xffxfdax80x3xa6x4x4bbxfcx1x2x6x16mx61inToolx42x61rx1xffxffxffxff"x66ormx61ttingToolx62x61rx1x1xa4xffxffxffxff insx65rtingToolx62x61rx1x2x18xffxffxffxff"x65nx63ryptionToolx62x61rx1x2x8cxffxffxffxffx1awinx64owToolx62x61rx1x3xffxffxffxffx16quitToolx62x61rx1x4x4xffxffxffxff)

[appMetrics]
disableAppHeartbeat=false
disableTracking=false
notificationShown=true

[networking]
ignoreSSLErrors=true
proxyType=0

[ownCloud]
password=""
serverUrl=
todoCalendarBackend=0
todoCalendarEnabledList=@Invalid()
todoCalendarEnabledUrlList=@Invalid()
todoCalendarUrlList=@Invalid()
userName=

[savedSearches]
noteFolder-1=Note 2016-07-18T18.59.49, Note 2016-07-18T15.44.22, Note 2016-07-18T12.33.25, Note 2016-07-15T15.22.37, Note 2016-07-14T15.26.17, Note 2016-07-14T15.16.23, Note 2016-07-14T15.01.57

This topic has been deleted. Only users with topic management privileges can see it.

  • Hi All,

    I have used Qmutex in my project and when i close the application getting an crash saying «destroying locked mutex». Then i removed the use of mutex variables and then also i am getting the same error. I have used threads in my application and quitting them once work is done. Not sure from where i am getting this mutex error.
    I have used QSharedmemory in my application to make the application to have only one instance at a given point of time. Even i removed that, but still getting the error.

    Please suggest us how we can solve this issue.

    Thanks & Regards,
    Pradeep

  • @Pradeep-NS The error message tells you what the problem is: you are destroying a locked mutex. So, when your app is closed there is a locked mutex which then destroyed. You need to make sure you unlock the mutex when exiting the application.
    Please also check documentation: https://doc.qt.io/qt-5/qmutex.html#dtor.QMutex

  • @jsulm Even i have removed the usage of mutex from my application, but still getting this error message

  • @Pradeep-NS Are you sure you removed all mutexes?
    Did you do a complete rebuild of your application (delete build folder, run qmake and build)?
    Also if your app is crashing you can run it in debugger and check the stack trace to see where exactly it is crashing (use debug build).

  • Run with QT_FATAL_WARNINGS environment variable set and extract a stack trace. Paste it here.

  • Nominate our 2022 Qt Champions!

    This topic has been deleted. Only users with topic management privileges can see it.

    • Hi mates

      I got that warning (and application crash) for the following code:

          for (const QString &video : videoFiles)
          {
              ThumbnailExtractor *extractor = new ThumbnailExtractor(counter, folderPath + '/' + video);
              QThread *thread = new QThread();
              extractor->moveToThread(thread);        
      
              connect(thread, SIGNAL(started()), extractor, SLOT(generateThumbnail()), Qt::QueuedConnection);
              connect(extractor, SIGNAL(finished()), thread, SLOT(quit()), Qt::QueuedConnection);
      
              //automatically delete thread and thumbnail extractor object when work is done
              connect(extractor, SIGNAL(finished()), extractor, SLOT(deleteLater()));
              connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
      
              thread->start();
       }
      

      ThumbnailExtractor is not using QMutex at all, the crashing one comes from QThread. What I’ve messed up?

    • @MasterBLB said in Mysterious QMutex destroying locked mutex:

      ThumbnailExtractor is not using QMutex at all, the crashing one comes from QThread. What I’ve messed up?

      I seems to me that ThumbnailExtractor have QObject based members which are created in constructor but which stays in current thread.

      Are you sure all QObject base members for this class are created in generateThumbnail() or have the class instance as parent?

    • Indeed it has:

      class ThumbnailExtractor : public QObject
      {
          Q_OBJECT
      ....
      private:
          QMediaPlayer *player;
          ThumbailVideoSurface *surface;
          QMediaContent content;//that's not a descendant of QObject
      .....
      };
      

      however, in the constructor I have:

      ThumbnailExtractor::ThumbnailExtractor(int counter, const QString &videoFilePath, QObject *parent)
      : QObject(parent), content(videoFilePath)
      {    
          player = new QMediaPlayer(this);
          surface = new ThumbailVideoSurface(counter, this);
          player->setVideoOutput(surface);
          connect(surface, SIGNAL(stopMedia()), player, SLOT(stop()), Qt::QueuedConnection);
          connect(surface, SIGNAL(stopMedia()), this, SIGNAL(finished()), Qt::QueuedConnection);
      
          player->setMuted(true);
      
          connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(error(QMediaPlayer::Error)));//, Qt::QueuedConnection);
          connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));//, Qt::QueuedConnection);
      }
      

      so yeah, these should be moved to another thread along with ThumbnailExtractor object.

    • @MasterBLB said in Mysterious QMutex destroying locked mutex:

      so yeah, these should be moved to another thread along with ThumbnailExtractor object.

      What about ThumbailVideoSurface ?

    • @KroMignon said in Mysterious QMutex destroying locked mutex:

      @MasterBLB said in Mysterious QMutex destroying locked mutex:

      so yeah, these should be moved to another thread along with ThumbnailExtractor object.

      What about ThumbailVideoSurface ?

      It does not contain any member variables.
      EDIT:
      Wrong! It has just one int member; I meant it does not contain any QObject-related members.

    • @MasterBLB I had troubles with QSoundEffect and thread changes.

      I don’t know if QMediaPlayer does not have same kind of problems.

      My suggestion would be to create QMediaPlayer instance when runnin in right thread.

    • @MasterBLB said in Mysterious QMutex destroying locked mutex:

      it does not contain any QObject-related members.

      Given the name, are you by any chance using QPixmap in it?

      From https://doc.qt.io/qt-5/thread-basics.html#gui-thread-and-worker-thread

      All widgets and several related classes, for example QPixmap, don’t work in secondary threads.

    • I’m using QImage:

      bool ThumbailVideoSurface::present(const QVideoFrame &frame)
      {
          if (frame.isValid())
          {
              QImage thumbnail(frame.image());
              thumbnail.save("thumbnail" + QString::number(tempCounter) + ".png");//that's only temporary, finally I'm going to create some kind of QMap <fileName, thumbnail QPixmap/QImage>
      
              //stop();//to wykrzacza aplikację
              emit stopMedia();
          }
      
          return true;
      }
      

      but I was going to switch to QPixmap later on, for rescaling the image.

    • Moving creation of QMediaPlayer in the new QThread didn’t helped as well.

    • @MasterBLB said in Mysterious QMutex destroying locked mutex:

      ThumbnailExtractor is not using QMutex at all, the crashing one comes from QThread. What I’ve messed up?

      You don’t wait for the thread to finish from what I can tell. Also when diagnosing crashes, please provide a stack trace.

    • A try to check stack frame was the 1st I’ve tried before writing the post, sadly there is none. Besides, pls explain me how I don’t wait for the thread to stop before deleting if I have the lines:

      connect(extractor, SIGNAL(finished()), thread, SLOT(quit()), Qt::QueuedConnection);
      connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
      
    • @MasterBLB said in Mysterious QMutex destroying locked mutex:

      A try to check stack frame was the 1st I’ve tried before writing the post, sadly there is none.

      If you don’t have a stack trace, then the program is not running. There’s no crash without a stack is the point. If you simply get a warning from the Qt runtime, then run your program in the debuger with the environment variable QT_FATAL_WARNINGS set to 1 so it trips at the point of the actual error and then extract the stack trace.

      Besides, pls explain me how I don’t wait for the thread to stop before deleting if I have the lines:

      QThread::wait (equivalent to std::thread::join) comes to mind. The fact that a signal was raised doesn’t mean that the thread (which is simply a ‘special’ function) has finished executing.

    • @kshegunov said in Mysterious QMutex destroying locked mutex:

      If you don’t have a stack trace, then the program is not running. There’s no crash without a stack is the point. If you simply get a warning from the Qt runtime, then run your program in the debuger with the environment variable QT_FATAL_WARNINGS set to 1 so it trips at the point of the actual error and then extract the stack trace.

      I mean there is no readable/useful stack frame, neither I don’t know which of over 100 threads listed in debugger is the one I should check.

      I tried that QT_FATAL_WARNINGS before, sadly due to some crap with QML («QML QQuickText: Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead.») I won’t even reach the code part which contains threads.

    • Humor me, will you?

      constexpr int poolSize = 16;
      QVector<QThread *> threadPool(poolSize);
      
      QCoreApplication * app = QCoreApplication::instance();
      for (size_t i = 0; i < poolSize; i++)  {
          QThread * thread = new QThread(app);
          thread->start();
      
          QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
      }
      QObject::connect(app, &QCoreApplication::aboutToQuit, [threadPool] () -> void {
          for (QThread * thread : threadPool)  {
              thread->quit();
              thread->wait();
          }
      });
      
      int index = 0;
      for (const QString &video : videoFiles)
      {
          ThumbnailExtractor *extractor = new ThumbnailExtractor(counter, folderPath + '/' + video);
          extractor->moveToThread(threadPool[index++ % poolSize]);
      
          QObject::connect(extractor, &ThumbnailExtractor::finished, extractor, &QObject::deleteLater);
          QMetaObject::invokeMethod(extractor, &ThumbnailExtractor::generateThumbnail, Qt::QueuedConnection);
      }
      

      A note here:
      QMediaPlayer and related classes don’t seem to be reentrant so you can’t use them from different threads. Stick to the main one.

    A, QMutex source as the source destructor

    QMutex::~QMutex()
    {
    	QMutexData *d = d_ptr.load();
    	if (isRecursive()) 
    		delete static_cast<QRecursiveMutexPrivate *>(d);
    	} else if (d) 
    	# ifndef QT_LINUX_FUTEX
    	if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.load()&& tryLock()) 
    		unlock();
    		return;
    	}
    	# endif
    	qWarning("QMutex: destroying locked mutex");
    	}
    }
    

    Second, the solution of this error

    The main reason is «destructor a mutex lock in a locked state»

    Generally appear in close qt application time. Mainly qt program exits when the first destruction of the mutex before stopping thread caused.

    Solution: Do not qt application main functions directly open any thread. It should open in the UI thread multithreading, such as opening a thread in the constructor mainWindow inside the main window, this error does not occur.

    The reason your open thread ui thread when program exits not appear above error is that the UI thread open thread is subject qt managed to exit the program when the recovery resources, qt program open thread can stop correctly. «: Destroying locked mutex QMutex» and therefore does not appear. And you open directly in the main function thread, it will not be stopped correctly, or that will not stop until recovery resources. Resulting in a destructor QMutex still in the locked state.

    Понравилась статья? Поделить с друзьями:
  • Dem f600 ошибка e1
  • Delta ошибка e14
  • Dell световая индикация ошибок
  • Debian ошибка установки пакета
  • Dead by daylight ошибка 300