You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++多线程加速文件数据传输无效果,求问题排查与优化方案

问题描述

本人为C++初学者,编写代码将input.txt中的189156个数字传输至test.txt,单线程执行耗时约23秒。尝试使用4个线程各处理1/4数据以提升速度,但执行后耗时无变化。附上代码如下:

// This program reads data from a file into an array.

#include <iostream>
#include <fstream> // To use ifstream
#include <vector>
#include <thread>
using namespace std;

void test(int start, int end)
{
    std::vector<int> numbers;
    ifstream inputFile("input.txt");        // Input file stream object

    // Check if exists and then open the file.
    if (inputFile.good()) {
        // Push items into a vector
        int current_number = 0;
        while (inputFile >> current_number) {
            numbers.push_back(current_number);

        }

        // Close the file.
        inputFile.close();

        // Display the numbers read:
        cout << "The numbers are: ";
        for (int count = start ; count < end; count++) {
           cout << numbers[count] << " " ;


            std::ofstream ofs;
            ofs.open("test.txt", std::ofstream::out | std::ofstream::app);

            ofs << numbers[count] << endl;

            ofs.close();

        }

        cout << endl;
    }
    else {
        cout << "Error!";
        _exit(0);
    }


}


int main() {

    std::thread worker1(test, 0, 50000); 
    std::thread worker2(test, 50000, 100000);
    std::thread worker3(test, 100000, 150000);
    std::thread worker4(test, 150000, 189156);
    worker1.join();
    worker2.join();
    worker3.join();
    worker4.join();
   

    return 0;
}

请问该场景是否适合使用多线程?若适合,请指出代码中的错误;若不适合,请给出正确的提速方法。

问题分析与解答

是否适合多线程?

这个场景不适合用多线程提速。因为文件读写属于磁盘IO密集型任务,磁盘(尤其是机械硬盘)的并行读写能力非常有限,多线程不仅无法发挥并行优势,反而会因为重复IO、资源竞争带来额外开销,甚至拖慢执行速度。

代码中的核心错误

  • 重复读取输入文件:每个线程都完整读取了一遍input.txt,相当于总共读了4次文件,这是极大的资源浪费,直接抵消了多线程的可能收益
  • 频繁打开/关闭输出文件:每个线程在循环里每写一个数字就打开、关闭一次test.txt,频繁的文件IO操作会大幅增加耗时
  • 无保护的并发写文件:多个线程同时往test.txt追加内容,即使使用app模式,也可能导致输出内容乱序或部分数据丢失,同时增加磁盘IO的竞争冲突

正确的提速方法

针对IO密集型的文件转写任务,优化核心是减少IO次数、提升单次IO的吞吐量,推荐以下方案:

方案1:单线程优化(最有效)

一次性读取全部数据到内存,再一次性写入输出文件,避免频繁IO操作:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers;
    ifstream inputFile("input.txt");
    if (!inputFile.is_open()) {
        cout << "Error opening input file!" << endl;
        return 1;
    }

    // 一次性读取所有数据到内存
    int num;
    while (inputFile >> num) {
        numbers.push_back(num);
    }
    inputFile.close();

    // 一次性打开输出文件,写入所有数据
    ofstream outputFile("test.txt");
    if (!outputFile.is_open()) {
        cout << "Error opening output file!" << endl;
        return 1;
    }
    for (int n : numbers) {
        outputFile << n << '\n'; // 用'\n'替代endl,减少缓冲区强制刷新
    }
    outputFile.close();

    return 0;
}

方案2:分块读写(适合超大型文件)

如果文件过大无法一次性载入内存,可以采用大分块的方式读写,减少IO次数:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

const int BLOCK_SIZE = 10000; // 每次读取10000个数字

int main() {
    ifstream inputFile("input.txt");
    if (!inputFile.is_open()) {
        cout << "Error opening input file!" << endl;
        return 1;
    }

    ofstream outputFile("test.txt");
    if (!outputFile.is_open()) {
        cout << "Error opening output file!" << endl;
        return 1;
    }

    vector<int> block(BLOCK_SIZE);
    int count;
    while (true) {
        count = 0;
        // 读取一个块的数据
        while (count < BLOCK_SIZE && inputFile >> block[count]) {
            count++;
        }
        if (count == 0) break;
        // 写入这个块的数据
        for (int i = 0; i < count; i++) {
            outputFile << block[i] << '\n';
        }
    }

    inputFile.close();
    outputFile.close();
    return 0;
}

额外优化建议

  • 避免使用endl:endl会强制刷新缓冲区,增加IO次数;改用'\n',由系统自动管理缓冲区刷新时机
  • 增大文件流缓冲区:可以用rdbuf()->pubsetbuf()手动设置更大的缓冲区,进一步减少底层IO操作次数

内容的提问来源于stack exchange,提问作者ZIKO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:25:28