C++的有效字数统计多线程
Effective wordcount multithreading in C++
我对C++和多线程相当陌生,需要一些帮助来创建字数统计,以有效地在多个线程之间划分工作。
假设,我有一个函数来计算一行(字符串(中的单词:
count_words_in_line(line);
对于一个线程,行中的总字数是每行此函数输出的简单总和,但是如何将其划分为线程?
我的想法是使用两个线程 - 一个用于计算偶数行,一个用于计算奇数行,但代码会导致分段错误。
我做错了什么?有没有更好的方法?
我不想使用线程池,理想情况下,我想指定参数中的线程数,以衡量多线程实现的性能。
这是我的相关代码:
bool odd = true;
auto thread_count_odd = [&counter, &infile, &odd, &line, &mutex]() {
while (std::getline(infile, line)) {
if (odd) {
std::cout<<"Count odd"<<std::endl;
mutex.lock();
counter += count_words_in_line(line);
mutex.unlock();
}
odd = !odd;
}
};
bool even = false;
auto thread_count_even = [&counter, &infile, &even, &line, &mutex]() {
while (std::getline(infile, line)) {
if (even) {
std::cout<<"Count even"<<std::endl;
mutex.lock();
counter += count_words_in_line(line);
mutex.unlock();
}
even = !even;
}
};
std::thread t1(thread_count_odd);
std::thread t2(thread_count_even);
t1.join();
t2.join();
- 使用具有读索引/写索引和互斥/条件变量的共享向量(如 Jarod42 所建议的那样(。
- 启动计数线程,等待写入索引大于读取索引。
- 让主线程读取行并填充向量并相应地通知条件变量。
- 当计数线程看到写入索引已增加时,它们可以读取该行并进行计数。
- 主线程指示文件已完全读取。 计数线程返回由
join()
传递的结果。 因此可以添加结果。
备注:可能只有一个线程将执行计数,这表明不需要其他线程。 至少有 2 个线程:读取线程和处理线程。
我认为问题是你必须在getline调用周围有一个互斥锁。两个线程同时访问文件,这可能会导致问题。
我有这段代码,可以使用条件变量适用于您的情况。希望这有帮助
'
#include<iostream>
#include<thread>
#include<string>
#include<mutex>
#include<condition_variable>
#include<unistd.h>
#include <fstream>
#define MAX_THREADS 50
using namespace std;
thread *threads = new thread[MAX_THREADS];
condition_variable cv[MAX_THREADS];
mutex m1;
int counter=0;
int count_words_in_line(string line){
/*write your code here*/
return 1;
}
void printString(int tid, ifstream &inFile, int tcount)
{
unique_lock<mutex> lock(m1);
while(1)
{
string line;
inFile >> line;
string a = "";
if(line==a)break;
cv[(tid+1)%tcount].notify_one();
cv[tid].wait(lock);
counter += count_words_in_line(line);
}
cv[(tid+1)%tcount].notify_one();
}
int main(int argc, char** argv)
{
int tcount, ccount, k;
std::ifstream inFile;
string name;
inFile.open("input.txt");
string str;
tcount = 2;
for(int i = 0; i < tcount; i++) {
threads[i] = thread(printString, i, ref(inFile), tcount);
}
for (int i = 0; i < tcount; i++)
threads[i].join();
cout << counter << endl;
return 0;
}
'
如果线程仅从文件中读取,则不需要互斥锁。您可以让 txt 文件中的线程数跳过行,以便每个线程都有自己的行要读取,然后合并结果。适用于大文件>1GB 例如:
void readerThread(char *argv[], std::unordered_set<std::string>& uniqueWords, size_t threadIndex, size_t maxThreads)
{
std::ifstream fin (argv[1]);
if (fin.is_open())
{
std::string line;
for (size_t i = 1; i < threadIndex; i++)
{
fin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
while (fin)
{
getline(fin, line);
std::string word;
std::stringstream ss (line);
while (getline (ss, word, ' '))
{
uniqueWords.insert (word);
}
for (size_t i = 1; i < maxThreads; i++)
{
fin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
}
}
else
{
throw std::invalid_argument("file error");
}
}
主要:
const auto processorCount = std::thread::hardware_concurrency();
std::vector<std::unordered_set<std::string>> vecOfSet;
std::unordered_set<std::string> uniqueWords;
unsigned int uniqueWordsCount = 0;
for(size_t threads = 0; threads < processorCount; threads++)
{
vecOfSet.emplace_back(std::unordered_set<std::string>());
}
std::vector<std::thread> threads_;
for(size_t threads = 0; threads < processorCount; threads++)
{
std::thread thread_([ &vecOfSet, threads, argv, processorCount]() { readerThread( argv, std::ref(vecOfSet.at(threads)), threads+1, processorCount);});
threads_.push_back(std::move(thread_));
}
for(size_t threads = 0; threads < processorCount; threads++)
{
threads_.at(threads).join();
}
for(size_t threads = 0; threads < processorCount; threads++)
{
uniqueWords.merge(vecOfSet.at(threads));
}
uniqueWordsCount = uniqueWords.size();
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程比没有线程C++慢
- 具有 C++11 多线程的特征库
- 通过安装信号处理程序关闭多线程应用程序
- 成员变量在多线程 C++ 时自行更改
- C++的有效字数统计多线程