【发布时间】:2015-09-03 11:48:31
【问题描述】:
底线
如何确保线程私有实例被正确销毁?
背景
在回答 this question 时,我在 VS2013 中使用 Intel C++ 15.0 编译器时遇到了一个奇怪的问题。声明全局变量threadprivate 时,从属线程副本不会被破坏。我开始寻找迫使他们毁灭的方法。在this 站点,他们说添加 OMP 屏障应该会有所帮助。它没有(参见 MCVE)。我尝试将 OMP 阻塞时间设置为 0,以便线程不应该在并行区域之后停留(也没有帮助)。我尝试添加一些延迟主线程的虚拟计算,让其他线程有时间死掉。仍然没有帮助。
MCVE:
#include <iostream>
#include <omp.h>
class myclass {
int _n;
public:
myclass(int n) : _n(n) { std::cout << "int c'tor\n"; }
myclass() : _n(0) { std::cout << "def c'tor\n"; }
myclass(const myclass & other) : _n(other._n)
{ std::cout << "copy c'tor\n"; }
~myclass() { std::cout << "bye bye\n"; }
void print() { std::cout << _n << "\n"; }
void add(int t) { _n += t; }
};
myclass globalClass;
#pragma omp threadprivate (globalClass)
int main(int argc, char* argv[])
{
std::cout << "\nBegninning main()\n";
// Kill the threads immediately
kmp_set_blocktime(0);
#pragma omp parallel
{
globalClass.add(omp_get_thread_num());
globalClass.print();
#pragma omp barrier
//Barrier doesn't help
}
// Try some busy work, takes a few seconds
double dummy = 0.0;
for (int i = 0; i < 199999999; i++)
{
dummy += (sin(i + 0.1));
}
std::cout << dummy << "\n";
std::cout << "Exiting main()\n";
return 0;
}
输出是
def c'tor
开始 main()
def c'tor
1
def c'tor
3
def c'tor
2
0
1.78691
退出 main()
再见
只有一个“再见”,而我原以为是四个。
更新
遵循 Kyle's 引用的 OMP 4.0 标准的声明
线程私有变量的所有副本的存储空间根据静态变量在基础语言中的处理方式被释放,但在程序中未指定的位置。
我添加了一个类的静态实例(全局和本地)来查看它的析构函数是否被调用。它确实适用于本地和全球案例。所以问题仍然存在。
【问题讨论】: