Эффективная многопоточность в Wordcount в Stack Overflow

Я довольно новичок в 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();

0

Решение

  • Используйте общий вектор с read-index / write-index и mutex / condition-variable (как предложено Jarod42).
  • Запустите подсчет потоков, ожидая, что индекс записи будет больше индекса чтения.
  • Позвольте основному потоку читать строки, заполнить вектор и соответственно уведомить условную переменную.
  • Когда подсчитывающие потоки видят, что индекс записи увеличился, они могут прочитать строку и выполнить подсчет.
  • Основной поток указывает, что файл прочитан полностью. Подсчет потоков возвращает результат, который передается join(), Таким образом, результаты могут быть добавлены.

Примечание: возможно, что только один поток будет выполнять подсчет, который будет указывать, что другие потоки не были нужны. Существует как минимум 2 потока: поток чтения и поток обработки.

0

Другие решения

Я думаю, проблема в том, что у вас должен быть мьютекс вокруг вызова getline. Оба потока одновременно обращаются к infile, что может вызвать проблемы.

У меня есть этот код, который будет работать для вашей ситуации, используя условные переменные. Надеюсь это поможет

`

#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;
}

`

0

По вопросам рекламы [email protected]