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

多线程统计文件单词数:chunkSize≥2时程序报错求助

多线程单词统计程序的问题修复

问题分析

你的代码没法实现并行计算,还会在chunkSize≥2时触发报错,核心问题有这几个:

  • 锁的使用完全错误:线程t1启动后直接锁住互斥量,直到整个分块流程结束才解锁,导致t2全程阻塞,完全没有并行执行的效果,和单线程运行没区别。
  • t2的循环逻辑错误:你用i < chunkSize作为循环终止条件,这会只处理前chunkSize个分块,但实际分块数量是总行数/chunkSize向上取整——比如总共有10行、chunkSize=2时,分块数是5,你只处理前2个会漏统计;如果总行数少于chunkSize,还会直接访问不存在的chunks[i],触发数组越界报错。
  • 线程执行顺序未同步:t2可能在t1还没生成完分块时就去读取chunks,此时chunks内的元素还未填充,同样会引发越界访问。

修复方案

重新设计逻辑:主线程先完成文件读取和分块操作,再启动多个线程并行处理不同分块,用互斥量保护全局结果的累加过程,确保线程安全。

修复后的代码:

#include<iostream>
#include<fstream>
#include <mutex>
#include <thread>
#include <sstream>
#include <vector>

std::mutex result_mutex;
unsigned long long total_res = 0;

int countWords(const std::string& str) {
    std::stringstream ss(str);
    std::string word;
    int count = 0;
    while (ss >> word) {
        count++;
    }
    return count;
}

// 统计单个分块的单词数,并安全累加至全局结果
void countChunkWords(const std::vector<std::string>& chunk) {
    int chunk_count = 0;
    for (const auto& line : chunk) {
        chunk_count += countWords(line);
    }
    // 用lock_guard自动管理锁,避免死锁
    std::lock_guard<std::mutex> lock(result_mutex);
    total_res += chunk_count;
}

int main()
{
    char pat[100];
    std::cin >> pat;

    std::ifstream fin(pat);
    if (!fin.is_open()) {
        std::cerr << "打开文件失败。" << std::endl;
        return 1;
    }

    std::vector<std::string> textSplit;
    std::string line;
    while (std::getline(fin, line)) {
        textSplit.push_back(line);
    }
    fin.close();

    std::cout << "输入分块大小: ";
    size_t chunkSize{};
    std::cin >> chunkSize;

    size_t totalLength = textSplit.size();
    std::vector<std::vector<std::string>> chunks;

    // 主线程完成分块,无需额外线程处理
    for (size_t i = 0; i < totalLength; i += chunkSize) {
        auto start = textSplit.begin() + i;
        auto end = textSplit.begin() + std::min(i + chunkSize, totalLength);
        chunks.emplace_back(start, end);
    }

    // 创建线程,每个线程负责一个分块的统计
    std::vector<std::thread> threads;
    for (const auto& chunk : chunks) {
        threads.emplace_back(countChunkWords, std::ref(chunk));
    }

    // 等待所有线程执行完成
    for (auto& t : threads) {
        t.join();
    }

    std::cout << "\n总单词数: " << total_res << std::endl;
    return 0;
}

关键修改点

  1. 分块逻辑移至主线程:分块是简单的数组分割操作,主线程处理即可,无需额外线程。
  2. 线程分工明确:启动与分块数量一致的线程,每个线程独立统计对应分块的单词数,真正实现并行计算。
  3. 正确使用锁:仅在累加全局结果时加锁,用std::lock_guard自动管理锁的生命周期,避免死锁风险。
  4. 修正循环逻辑:遍历所有分块进行统计,确保文件内容被完整计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:13