繁体   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