Итак, я пытаюсь использовать многопоточность алгоритма Sieve of Eratosthenes, используя pthreads. Это мой код.
#include <iostream>
#include <iomanip>
#include <math.h>
#include <thread>
#include <string.h>
#include <chrono>
#include <vector>
#include <stdlib.h>
#include <pthread.h>
struct Thread_data {
int thread_id;
std::vector<int> prime_seed_vect;
std::vector<int> chunk_vect;
};
void *calc_primes(void* td){
Thread_data *td_t = (Thread_data *)td;
std::vector<int> primes = td_t->prime_seed_vect;
std::vector<int> chunk = td_t->chunk_vect;
int chunk_start = chunk.front();
int chunk_end = chunk.back();
std::cout << "chunk_start: " << chunk_start << std::endl;
std::cout << "chunk_end: " << chunk_end << std::endl;
int k;
int mult;
int mark;
for(std::vector<int>::size_type i=1; i!=primes.size(); i++){
k = primes[i];
mult = round(chunk_start/k);
mark = k*mult;
while(mark <= chunk_end){
chunk[mark - chunk_start] = 0;
mult += 1;
mark = k*mult;
}
}
std::cout << "primes: " << k << std::endl;
for(int i=0; i<(chunk_end-chunk_start); i++){
if(chunk[i] != 0){
std::cout << chunk[i] << " " << std::endl;
}
}
std::cout << " done " << std::endl;
}
int main(int argc, char *argv[]){
if(argc != 3){
std::cout << "Run program on format \"./sieve max num_of_threads\"" << std::endl;
return 0;
}
int num_threads = std::stoi(argv[2]);
std::cout << "Threads: " << num_threads << std::endl;
int max = std::stoi(argv[1]);
std::cout << "max: " << max << std::endl;
int sqrt_max = sqrt(max);
std::cout << "sqrt_max: " << sqrt_max << std::endl;
int chunk_size = (max-sqrt_max)/num_threads;
std::cout << "chunk_size: " << chunk_size << std::endl;
if(num_threads > (max-sqrt_max)){
std::cout << "Not enough work for this amount of threads. exiting..." << std::endl;
return 0;
}
std::vector<int> max_vect;
std::vector<int> prime_seeds;
for(int i=0; i<max; i++){
max_vect.push_back(i+1);
}
std::cout << "max start: " << max_vect.front() << std::endl;
std::cout << "max end: " << max_vect.back() << std::endl;
int k = 2;
int mult;
int mark;
//single thread part
while(k*k <= sqrt_max){
//set all multiples of k to 0 (mark them)
mult = k;
mark = k*mult;
while(mark <= sqrt_max){
max_vect[mark-1] = 0;
mult += 1;
mark = k*mult;
}
//find smallest unmarked number that is greater than k and set k to that number
for(int i=k; i<=sqrt_max; i++){
if(max_vect[i] != 0){
k = max_vect[i];
break;
}
}
}
//put all unmarked numbers(primes) in a vector
for(int i=0; i<=sqrt_max;i++){
if(max_vect[i] != 0){
prime_seeds.push_back(max_vect[i]);
}
}
//multithread part
pthread_t threads[num_threads];
Thread_data td[num_threads];
//give the seeds to all threads through a struct
for(int i=0; i<num_threads; i++){
int chunk_start = (i*chunk_size) + (sqrt_max + 1);
int chunk_end;
if(i == (num_threads-1)){
chunk_end = chunk_start + chunk_size +((max - sqrt_max) % num_threads);
}
else{
chunk_end = chunk_start + chunk_size;
}
td[i].thread_id = i;
std::vector<int> temp1;
for(int j=chunk_start; j<chunk_end; j++){
temp1.push_back(j);
}
td[i].chunk_vect = temp1;
td[i].prime_seed_vect = prime_seeds;
}
for(int i=0; i<num_threads; i++){
pthread_create(&threads[i], NULL, calc_primes, &(td[i]));
}
std::cout << " After create " << std::endl;
for(int i=0; i<num_threads; i++){
std::cout << " inside join1 " << std::endl;
pthread_join(threads[i], NULL);
std::cout << " inside join2 " << std::endl;
}
std::cout << " After join " << std::endl;
return 0;
}
Я компилирую с g++ -Wall -g -pthread -std=c++11 -o sieve.cpp
, и когда я запускаю программу с ./sieve 35 1
(я ищу простые числа до 35 с 1 потоком), все работает нормально иЯ могу найти все простые числа и программа завершается правильно, но когда я запускаю ./sieve 36 1
, я получаю эту ошибку:
free(): invalid pointer
Aborted (core dumped)
Кажется, что ошибка возникает в pthread_join, поэтому я, вероятно, ссылаюсь на некоторый объект, который не 'больше не существует? Проблема возникает при работе с более чем одним потоком. Я ценю все предложения и помощь!