2015-05-02 4 views
2

Мне нужен счетчик потокобезопасности для количества текущих объектов типа Apple. Я попытался сделать простой с OpenMP, но я не понимаю, почему подсчет неверен. Вот упрощение класса, с фактическим тестового кода и фактического выхода:C++ счетчик объектов OpenMP неверный счет с std :: vector объектов

класса

class Apple { 

public: 

    Apple(); 
    ~Apple(); 
    static int getThreadCount(); 

private: 

    static int threadCount; 
    void threadCountIncrease(); 
    void threadCountDecrease(); 

}; 

Apple::Apple() { 
    threadCountIncrease(); 
} 

Apple::~Apple() { 
    threadCountDecrease(); 
} 

void Apple::threadCountIncrease() { 
    #pragma omp critical(AppleThreadCount) 
    { 
    std::cout << "## COUNT ++" << "\n"; 
    ++threadCount; 
    } 
} 

void Apple::threadCountDecrease() { 
    #pragma omp critical(AppleThreadCount) 
    { 
    std::cout << "## COUNT --" << "\n"; 
    --threadCount; 
    } 
} 

Тест кода

std::vector<Apple> apples; 
cout << Apple::getThreadCount() << "\n"; 
for(int i=0; i<3; ++i) { 
    apples.push_back(Apple()); 
    cout << Apple::getThreadCount() << "\n"; 
} 

Вывод, который я не понимаю

## COUNT ++ 
## COUNT -- 
0 
## COUNT ++ 
## COUNT -- 
## COUNT -- 
-1 
## COUNT ++ 
## COUNT -- 
## COUNT -- 
## COUNT -- 
-3 
## COUNT -- 
## COUNT -- 
## COUNT -- 

Почему существуют более «COUNT -» вхождения, чем «COUNT ++»? Почему последний показанный счет -3 вместо 3?


Благодаря принятым ответ, я в конечном счете отбрасывается, что я делал в пользу this solution.

ответ

2

Прежде всего хочу отметить, что мое объяснение может не полностью соответствовать техническим требованиям.

Единственное, что происходит, это то, что когда вы делаете apples.push_back(Apple());, тогда создается копия вашего элемента. Поскольку вы не определили конструктор копирования, threadCountIncrease не вызывается для этого копия.

Таким образом, вы получите как минимум в два раза больше --, затем ++.

В дополнение к этому std::vector будет - при увеличении размера - необходимо выделить больше памяти. В зависимости от реализации это приведет к перераспределению или копированию данных. В вашем случае имеется дополнительная копия .

При добавлении apples.reserve(10); прямо перед вами петли вы увидите, что граф -- будет уменьшаться, потому что std::vector уже зарезервировали места по крайней мере 10 элементов.

Смежные вопросы