qt 單獨執行緒實現日誌寫入功能

mkmkbj發表於2024-07-16

https://blog.csdn.net/u012329294/article/details/88286961

            <div id="content_views" class="htmledit_views">
                <p>在qt開發中,應用程式執行中常常會因為寫日誌的原因,造成系統效能低下,</p> 

那麼這個時候就應該考慮採用單獨的執行緒來實現日誌寫入功能了。

以下即為我實現的寫日誌程式碼。

1、qlog.h

  1. #ifndef LOG_H
  2. #define LOG_H
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <QDebug>
  6. #include <QMessageBox>
  7. #include <QFile>
  8. #include <QFileInfo>
  9. #include <QThread>
  10. #include <QList>
  11. #include <QSemaphore>
  12. #include <QMutex>
  13. class Clog : public QThread
  14. {
  15. Q_OBJECT
  16. public:
  17. Clog();
  18. void write(const QString &msg);
  19. virtual void run();
  20. private:
  21. QMutex m_mutex;
  22. QList<QString> m_msg;
  23. QSemaphore m_synSem;
  24. };
  25. #endif // LOG_H

2、qlog.cpp

  1. #include "qlog.h"
  2. #include <QMutex>
  3. #include <QFile>
  4. #include <QApplication>
  5. #include <QDate>
  6. #include <QDebug>
  7. Clog::Clog(): m_synSem(0)
  8. {
  9. }
  10. void Clog::write(const QString &msg)
  11. {
  12. m_mutex.lock();
  13. QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
  14. QString current_date = QString("Jesus God! (%1)").arg(current_date_time);
  15. QString message = QString("%1 %2").arg(msg).arg(current_date);
  16. m_msg.push_back(message);
  17. m_mutex.unlock();
  18. m_synSem.release();
  19. }
  20. void Clog::run()
  21. {
  22. qDebug() << "run()";
  23. while (true)
  24. {
  25. m_synSem.acquire();
  26. m_mutex.lock();
  27. if (m_msg.isEmpty())
  28. {
  29. continue;
  30. }
  31. QString message = m_msg.front();
  32. m_msg.pop_front();
  33. QFile file("log.txt");
  34. file.open(QIODevice::WriteOnly | QIODevice::Append);
  35. QTextStream text_stream(&file);
  36. text_stream << message << "\r\n";
  37. file.flush();
  38. file.close();
  39. m_mutex.unlock();
  40. }
  41. }

3、main檔案

  1. Clog *g_log = new Clog();
  2. int main(int argc, char *argv[])
  3. {
  4. QApplication a(argc, argv);
  5. g_log->start();
  6. g_log->write("CTK EXE start...");
  7. return a.exec();
  8. }

以上注意這裡最關鍵的是:

執行緒中會有三個區域性變數,

m_mutex、
m_msg、
m_synSem

這三個變數是核心,m_msg是其他執行緒寫入本執行緒的訊息佇列。

m_mutex是對m_msg進行執行緒安全保護的互斥訊號量。

m_synSem是同步訊號量,當訊息佇列未進入時,執行緒處於阻塞狀態,可以避免while一直死迴圈。

只要對這三個變數理解清楚,就算掌握了單獨執行緒的開發之道。

</article>

相關文章