2

我正在通过 Qt 开发一个应用程序。

在这个应用程序中,主线程是一个 Web 服务器。另一个线程有时会从大文件 (250mb) 中读取数据并将它们写入输出文件 (~2gb)。

该线程对文件执行高 I/O 操作,CPU iowait 约为 70%。

我的问题是写入文件时,Web 服务器没有快速响应。我的理解是服务器的 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是尽可能快地生成文件。

我做错了什么?尽可能快地读/写文件是否安全?在上述功能中睡眠是强制性的吗?但是我们怎么知道好的时间片呢?

我正在使用 Intel Core i5 2500 和标准 HDD 驱动器开发 Mint LMDE、Linux 3.2.0 64 位。

编辑:重现问题的示例程序可在此处获得:https ://bugreports.qt-project.org/secure/attachment/30436/TestQtBlocked.zip 。需要qt的qmake编译。如果你运行它,它将创建一个空的 3GB 文件,工作线程将在启动时启动,并在几秒钟内创建文件。在此期间,如果您尝试连接到 http://localhost:8081/ 并运行许多 F5 刷新页面,您会看到有时它没有快速响应。如果有人可以用我的示例程序重现我的问题并告诉我,这可能会有所帮助。

4

2 回答 2

1

如果您正在饿死主线程的选择调用,请创建一个单独的线程来执行文件 I/O。当事件来自 Qt 时,触发某种 IPC 唤醒您的工作线程以执行大文件 I/O 并立即从您的事件处理程序返回。

(这假设异步写入文件对您的程序逻辑有意义。只有您才能确定这是否属实。)

于 2012-12-12T19:55:51.740 回答
0

来自手册页: size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

你想写 sizeBuf , 1 个元素。

您可能想使用 setvbuf 调整缓冲。

setvbuf(pOutfile, NULL, _IONBF, 0) - 禁用缓冲。

完整示例位于: http: //publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp ?topic=%2Frtref%2Fsetvbuf.htm

更好地切换到使用文件描述符,而不是文件流。

使用文件描述符,您可以使用 sendfile 和 slice。人发送文件人切片

于 2012-12-12T18:46:54.457 回答