[英]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.