簡體   English   中英

使用Qt中的工作線程將數據寫入文件的正確方法是什么?

[英]What is the correct way to write data to a file using worker thread in Qt?

我正在Qt中開發一個UI密集型的應用程序。 這是UI密集型的,因為我的應用程序顯示日志,而日志的速度非常快,並且UI必須反映出來。

現在,當日志數量超過一定數量后,我的以前的日志將開始被刪除,因為我的UI窗口有一個限制(100000個日志,以保持應用程序快速運行)。

因此,為了保存舊日志,我想在刪除舊日志之前將其寫入文件。

問題

如果我在主線程中寫入文件,我的UI會掛起(變得非常慢)。 因此,我決定在工作線程中寫入文件。 這就是我這樣做的:

我創建了自己的類WorkerThread ,該類繼承了QThread類,並在該類的run()方法內部,將數據寫入了文件。

我要寫入的數據存儲在線程成員變量本身中:

所以我的代碼是:

其他一些類的功能

WorkerThread *workerThread = new WorkerThread();
connect(workerThread, SIGNAL(resultReady()), workerThread, SLOT(quit()));
workerThread->attribute1 = dataToWrite1;
workerThread->attribute2 = dataToWrite2;
workerThread->start();

WorkerThread類

class WorkerThread : public QThread
{
Q_OBJECT

public:

  QString attribute1;
  QString attribute2;  

protected:
    void run() {    
            // DELIMITER IS ..:  //                 

            QFile myFile("C:/shiftedlines/myFile.txt");
            if(myFile.open(QIODevice::WriteOnly|QIODevice::Append))
            {    
                QTextStream stream(&myFile);
                stream<< attribute1<<"..:";
                stream<< attribute2<<"\n";   
            }
        emit resultReady();
    }
signals:
    void resultReady();
};

但是寫了大約500行之后,我的應用程序崩潰了 我該如何解決這個問題?

這不能解決您遇到的問題,但是由於您在注釋中提出了這個問題,因此這就是我過去實現此類任務的方式。

工人階級

class worker : public QObject
{
    Q_OBJECT

    public:
        worker();

    public slots:
        void start();

    signals:
        void finished();
};

主要

worker* cur_worker = new worker();

// move to its own thread
QThread* worker_thread = new QThread(this);
cur_worker->moveToThread(worker_thread);
QObject::connect(worker_thread, SIGNAL(started()), cur_worker, SLOT(start()));
QObject::connect(cur_worker, SIGNAL(finished()), worker_thread, SLOT(quit()));
QObject::connect(worker_thread, SIGNAL(finished()), worker_thread, SLOT(deleteLater()));

// start
worker_thread->start();

此示例不處理worker對象的銷毀,在您的情況下,您可能希望立即執行該銷毀。

只要正確完成,寫入文件的速度就應該很快。

慢的不是寫文件,而是打開文件。

確保您不會在每次收到日志時都打開/關閉文件,而是以只寫和追加模式打開文件, 在應用程序運行和寫入日志時保持打開狀態

通常,您可以以大約700MB / s的速度寫入最新的SSD驅動器,因此我懷疑您會對UI產生明顯影響。


如果您真的想使用線程(這可能是IMO的大材小用),請不要忘記確保線程安全,您必須使用信號/插槽與線程進行通信。

從您的代碼看來,您為每次日志寫入啟動了一個新線程,每個線程都試圖打開文件。 您的文件一次只能被一個線程寫入,這將被系統阻止,因此上面有1個線程可以寫入文件,那么擁有更多線程是沒有用的。

可能是您的線程陷入了試圖打開已經被其他人訪問的文件的困境,最終導致了數百個掛起的線程,如果您將它們放在堆棧中,則會導致內存溢出。

只要有寫東西,一次打開文件並寫的規則也適用於線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM