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