История изменений
Исправление AndreyKl, (текущая версия) :
#include <iostream>
#include <vector>
#include <iomanip>
#include <thread>
#include "tbb/concurrent_queue.h"
#define THREADS_CNT 10
using namespace std;
using namespace tbb;
class CSimpleNumbers {
private:
concurrent_queue<int> queue;
bool working = true;
public:
vector<unsigned char> numbers; // Array starts with 3 and has a step of 2: 3, 5, 7, 9 ...
inline uint NumberToIndex(const uint number) {return (number-3)/2;}; // TODO: number should not be < 3
inline uint IndexToNumber(const uint index) {return index*2+3;};
void MarkNonSimple(const uint v,const uint max);
void consumer(const uint me, const uint max); //worker
public:
void Initiate(const uint max=6); // Marking with multithreading
void Print();
bool IsSimple(uint number);
};
bool CSimpleNumbers::IsSimple(uint number)
{
uint i;
if ( number<4 )
return true;
if ( number % 2 == 0 )
return false;
for (i=0; i<NumberToIndex(number); i++)
if ( ( numbers[i] == 1 ) && ( number % IndexToNumber(i) == 0 ) )
return false;
return true;
};
void CSimpleNumbers::MarkNonSimple(const uint v,const uint max)
{
uint n = v*3;
while (n <= max) {
numbers[NumberToIndex(n)] = 0;
n += v*2;
}
};
void CSimpleNumbers::Print()
{
uint n = 3;
for (auto i : numbers) {
if (i == 1)
cout << n << " ";
n += 2;
}
cout << endl;
};
void CSimpleNumbers::Initiate(const uint max)
{
numbers.assign(NumberToIndex(max) + 1, 1);
vector<thread> threads;
for(uint i = 0; i < THREADS_CNT; i++) {
threads.push_back( thread(&CSimpleNumbers::consumer, this, i, max) );
}
for (uint head=3;head<=max;head+=2) {
if ( numbers[NumberToIndex(head)] == 1 ) // Is simple/unchecked yet
queue.push(head);
}
while(!queue.empty())
std::this_thread::sleep_for(std::chrono::milliseconds(250));
working = false;
for(auto& t : threads)
t.join();
};
void CSimpleNumbers::consumer(const uint me, const uint max) {
while(working) {
int n;
if(!queue.empty()) {
if(queue.try_pop(n)) {
if ( ! IsSimple(n) ) { // Is not simple
numbers[NumberToIndex(n)] = 0;
} else { // Is simple
MarkNonSimple(n, max);
}
}
} else { //queue.empty()
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
}
int main() {
CSimpleNumbers s;
s.Print();
s.Initiate(150000);
s.Print();
return 0;
}
конпеляем
g++ -I/home/myname/tmp/tbb41_20130314oss/includes -std=c++11 testqueue.cpp -o testqueue -L/home/myname/tmp/tbb41_20130314oss/build/linux_intel64_gcc_cc4.7_libc2.15_kernel3.5.0_release/ -ltbb
запускаем
LD_PRELOAD=/home/myname/tmp/tbb41_20130314oss/build/linux_intel64_gcc_cc4.7_libc2.15_kernel3.5.0_release/libtbb.so.2 ./testqueue
не пиши через жопу, пиши номрально. и всё будет работать. (hint: у тебя через жопу, у меня нормально).
твой код буду глядеть завтра. но чует моё сердце там банально выполняется работа только внутри IsSimple. поглядим.
Исходная версия AndreyKl, :
#include <iostream>
#include <vector>
#include <iomanip>
#include <thread>
#include "tbb/concurrent_queue.h"
#define THREADS_CNT 10
using namespace std;
using namespace tbb;
class CSimpleNumbers {
private:
concurrent_queue<int> queue;
bool working = true;
public:
vector<unsigned char> numbers; // Array starts with 3 and has a step of 2: 3, 5, 7, 9 ...
inline uint NumberToIndex(const uint number) {return (number-3)/2;}; // TODO: number should not be < 3
inline uint IndexToNumber(const uint index) {return index*2+3;};
void MarkNonSimple(const uint v,const uint max);
void consumer(const uint me, const uint max); //worker
public:
void Initiate(const uint max=6); // Marking with multithreading
void Print();
bool IsSimple(uint number);
};
bool CSimpleNumbers::IsSimple(uint number)
{
uint i;
if ( number<4 )
return true;
if ( number % 2 == 0 )
return false;
for (i=0; i<NumberToIndex(number); i++)
if ( ( numbers[i] == 1 ) && ( number % IndexToNumber(i) == 0 ) )
return false;
return true;
};
void CSimpleNumbers::MarkNonSimple(const uint v,const uint max)
{
uint n = v*3;
while (n <= max) {
numbers[NumberToIndex(n)] = 0;
n += v*2;
}
};
void CSimpleNumbers::Print()
{
uint n = 3;
for (auto i : numbers) {
if (i == 1)
cout << n << " ";
n += 2;
}
cout << endl;
};
void CSimpleNumbers::Initiate(const uint max)
{
numbers.assign(NumberToIndex(max) + 1, 1);
vector<thread> threads;
for(uint i = 0; i < THREADS_CNT; i++) {
threads.push_back( thread(&CSimpleNumbers::consumer, this, i, max) );
}
for (uint head=3;head<=max;head+=2) {
if ( numbers[NumberToIndex(head)] == 1 ) // Is simple/unchecked yet
queue.push(head);
}
while(!queue.empty())
std::this_thread::sleep_for(std::chrono::milliseconds(250));
working = false;
for(auto& t : threads)
t.join();
};
void CSimpleNumbers::consumer(const uint me, const uint max) {
while(working) {
int n;
if(!queue.empty()) {
if(queue.try_pop(n)) {
if ( ! IsSimple(n) ) { // Is not simple
numbers[NumberToIndex(n)] = 0;
} else { // Is simple
MarkNonSimple(n, max);
}
}
} else { //queue.empty()
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
}
int main() {
CSimpleNumbers s;
s.Print();
s.Initiate(150000);
s.Print();
return 0;
}
конпеляем
g++ -I/home/myname/tmp/tbb41_20130314oss/includes -std=c++11 testqueue.cpp -o testqueue -L/home/myname/tmp/tbb41_20130314oss/build/linux_intel64_gcc_cc4.7_libc2.15_kernel3.5.0_release/ -ltbb
запускаем
LD_PRELOAD=/home/myname/tmp/tbb41_20130314oss/build/linux_intel64_gcc_cc4.7_libc2.15_kernel3.5.0_release/libtbb.so.2 ./testqueue
не пиши через жопу, пиши номрально. и всё будет работать. (hint: у тебя через жопу, у меня нормально).