C++ OpenMP 对象计数器不正确计数 std::vector 个对象

C++ OpenMP object counter incorrect counts with std::vector of objects

我需要一个线程安全计数器来计算当前 Apple 类型对象的数量。我试图用 OpenMP 做一个简单的,但我不明白为什么计数不正确。这是 class 的简化版,带有实际测试代码和实际输出:

Class

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

我首先要说明,我的解释在技术上可能不完全正确。

发生的一件事是,当您执行 apples.push_back(Apple()); 时,会创建您的元素的 copy。因为您没有定义复制构造函数,所以不会为此 copy.

调用 threadCountIncrease

所以你最终得到的 -- 至少是 ++ 的两倍。

除此之外,std::vector 将 - 当它的大小增加时 - 需要分配更多内存。根据实施情况,这将导致重新分配或数据副本。在您的情况下,确实会发生额外的 copy

当您在循环之前添加 apples.reserve(10); 时,您会看到 -- 计数会减少,因为 std::vector 已经为 space 保留了至少10 个元素。