【发布时间】:2012-11-30 12:39:36
【问题描述】:
我正在通过 Qt 开发一个应用程序。
在这个应用程序中,主线程是一个 Web 服务器。另一个线程有时会从大文件 (250mb) 中读取数据并将它们写入输出文件 (~2gb)。
该线程对文件执行高 I/O 操作,CPU iowait 约为 70%。
我的问题是写入文件时,网络服务器没有快速响应。我的理解是服务器的 qt 套接字(在 Linux 上)由连接到 poll 或 select 事件系统的系统套接字表示。所以 Qt 只有在 poll 发出事件时才会向我的应用程序发送信号。
我认为文件写入的 io 操作太大可能会阻塞轮询系统,所以我的 qt 服务器没有收到套接字事件。当线程写完数据后,一切就正常了。
文件写法如下:
while(dataToRead){
// context has the list of files to read and current step
dataToRead = extractData(context, &pBuffer, &sizeBuf);
fwrite (pBuffer, 1, sizeBuf, pOutFile);
free(pBuffer);
pBuffer = NULL;
// usleep(100000);
}
如果我使用 usleep 功能添加中断,这有助于避免问题,但如果我没有使用足够大的睡眠,则不能完全避免。但是过大的sleep会破坏性能,而i是尽可能快的生成文件。
我做错了什么?尽可能快地读/写文件是否安全?在上述功能中睡眠是强制性的吗?但是我们怎么知道好的时间片呢?
我正在开发 Mint LMDE、Linux 3.2.0 64 位、Intel Core i5 2500 和标准 HDD 驱动器。
编辑: 可在此处获得重现该问题的示例程序:https://bugreports.qt-project.org/secure/attachment/30436/TestQtBlocked.zip。需要qt的qmake编译。如果你运行它,它将创建一个空的 3GB 文件,工作线程将在启动时启动,并在几秒钟内创建文件。在此期间,如果您尝试连接到 http://localhost:8081/ 并运行许多 F5 刷新页面,您会发现有时它没有快速响应。 如果有人可以用我的示例程序重现我的问题并告诉我,这可能会有所帮助。
【问题讨论】:
-
你要写多大的数据块?即 sizeBuf 的正常值是多少?
-
@Mike:它是 Qt,所以它是 C++。为什么他会使用
cstdio而不是fstream我无法理解。 -
@nos: 数据是JPEG图像,所以它可以从20Kb到200kb不等,sizeBuf不是静态的并且对应于图像大小。
-
@Mike:事实上,Qt 是针对我程序的高级部分,它使用用 C 或 c++ 代码编写的模块,但不使用 qt。
-
@Mike:250Mb 包含大量图片,extractData 函数在文件中搜索所需图片并将其复制到缓冲区中。是的,文件写入是在另一个线程中完成的。首先,我认为这是一个 Qt 问题,所以我制作了一个简单的测试程序来重现该问题。你可以在这里找到它:bugreports.qt-project.org/browse/QTBUG-28539