W aplikacji występuje wyścig. Proszę go wyeliminować dbając o to, aby rozwiązanie było skalowalne. Nie modyfikuj funkcji main
.
Aplikacja znajduje liczby pierwsze w kolekcji dostarczonych liczb.
W funkcji main
występują obiekty ref(x)
. Są to obiekty pomocnicze, które zapobiegają tworzeniu kopii obiektu, więc np.
thread thrd1( ref(p1) );
oznacza, że konstruktor std::thread
nie wykona kopii obiektu p1
.
Nie jest to kluczowe do znalezienia rozwiązania.
Posługujemy się także wektorem liczb z biblioteki standardowej, oraz iteratorem. Iterator pokazuje na element w kolekcji (element w wektorze)
#include <vector> #include <thread> #include <mutex> #include <random> #include <algorithm> #include <iterator> #include <iostream> using namespace std; const int N = 10000; class InputNumbers { public: InputNumbers(const vector<long>& n) : numbers(n), current(numbers.begin()) {} long getNext() { if( current < numbers.end() ) { return *(current++); } else { return 0; } } private: vector<long> numbers; vector<long>::const_iterator current; }; class OutputNumbers { public: OutputNumbers() {} void add(long n) { numbers.push_back(n); } vector<long>& get() { return numbers; } private: vector<long> numbers; }; //bada, czy n jest liczba pierwsza bool isPrime(long n) { if( n <= 3) return true; if( n % 2 == 0) return false; for(long i = 3; i * i <= n; i = i + 2) if(n % i == 0) return false; return true; } class ThreadPrime { public: ThreadPrime(InputNumbers& in, OutputNumbers& out) : input(in), output(out) { } //bada kolejne liczby z kolekcji input i dodaje liczbe do output, jezeli jest pierwsza void operator()() { for(long n = input.getNext(); n > 0; n = input.getNext() ) { if(isPrime(n) ) { output.add(n); } } } private: InputNumbers& input; OutputNumbers& output; }; int main () { vector<long> v(N); //wektor N liczb std::mt19937_64 gen; //generator losowy (Mersanne Twister, default seed) std::uniform_int_distribution<long> distr(1'000'000'000, 9'000'000'000); generate( v.begin(), v.end(), [&](){ return distr(gen);}); //N liczb losowych od 1*10^12 do 9*10^12 InputNumbers input(v); OutputNumbers output; ThreadPrime t1(input, output); ThreadPrime t2(input, output); thread thrd1( ref(t1) ); thread thrd2( ref(t2) ); thrd1.join(); thrd2.join(); cout << "num primes:" << output.get().size() << endl; copy( output.get().begin(), output.get().end(), ostream_iterator(cout, " ") ); //drukuje liczby pierwsze cout << endl; return 0; }