For the first time, I tried to use threads by myself in order to implement a parallel sieve of Eratosthenes. The trick is that each time a prime is found, a thread is spawned to eliminate all the multiples of this prime number from the boolean vector (the one that tells whether a number is a prime or not). Here is my code:
#include <cmath> #include <functional> #include <thread> #include <vector> // Invalidates the multiples of the given integer // in a given boolen vector template<typename Integer> void apply_prime(Integer prime, std::vector<bool>& vec) { for (Integer i = prime*2u ; i < vec.size() ; i += prime) { vec[i] = false; } } template<typename Integer> auto sieve_eratosthenes(Integer n) -> std::vector<Integer> { std::vector<bool> is_prime(n, true); std::vector<std::thread> threads; std::vector<Integer> res; auto end = static_cast<Integer>(std::sqrt(n)); for (Integer i = 2u ; i <= end ; ++i) { // When a prime is found, // * add it to the res vector // * spawn a thread to invalidate multiples if (is_prime[i]) { res.push_back(i); threads.emplace_back(apply_prime<Integer>, i, std::ref(is_prime)); } } for (auto& thr: threads) { thr.join(); } // Add the remaining primes to the res vector for (Integer i = end+1u ; i < is_prime.size() ; ++i) { if (is_prime[i]) { res.push_back(i); } } return res; } The primes are added in two steps to the res vector: every prime \$ p \$ such as \$ p < \sqrt{n} \$ is added when the prime is found, before the corresponding thread is thrown. The other primes are added at the end the of the function. Here is an example main:
int main() { auto primes = sieve_eratosthenes(1000u); for (auto prime: primes) { std::cout << prime << " "; } } I was pretty sure that I would get some problems due to parallelism, but for some reason, it seems to work. I got the expected results in the right order. Just to be sure, I would like to know whether my program is or correct or whether it has some threading issues that I couldn't see.
Note: I used many of the ideas from the answer to improve the code and wrote a follow-up question.