C++ C++;OpenMP对象计数器使用对象的std::vector计数不正确

C++ C++;OpenMP对象计数器使用对象的std::vector计数不正确,c++,multithreading,openmp,C++,Multithreading,Openmp,我需要一个线程安全计数器,用于计算当前类型为Apple的对象数。我试着用OpenMP制作一个简单的,但我不明白为什么计数不正确。下面是该类的简化,包括实际测试代码和实际输出: 课程 class Apple { public: Apple(); ~Apple(); static int getThreadCount(); private: static int threadCount; void threadCountIncrease();

我需要一个线程安全计数器,用于计算当前类型为
Apple
的对象数。我试着用OpenMP制作一个简单的,但我不明白为什么计数不正确。下面是该类的简化,包括实际测试代码和实际输出:

课程

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;
    }
}
为什么“计数--”出现的次数比“计数++”出现的次数多?为什么最后显示的计数是-3而不是3



多亏了被接受的答案,我最终放弃了我正在做的事情,转而支持它。

我首先要指出的是,我的解释在技术上可能并不完全正确

发生的一件事是,当你做
苹果时,向后推(Apple())然后创建元素的副本。由于尚未定义副本构造函数,因此不会为此副本调用
threadcountrease

因此,您将得到至少两倍于
--
++
的数量

除此之外,
std::vector
在其大小增加时需要分配更多内存。根据实施情况,这将导致重新分配或复制数据。在您的情况下,会出现额外的副本

当你添加一个
apples.reserve(10)
在循环之前,您将看到
--
计数将减少,因为
std::vector
已经为至少
10个
元素保留了空间

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 --