I'm using Intel C++ 15.0 (_OPENMP == 201307; i.e. the July 2013 version of OpenMP which is 4.0). According to the OMP 4.0 standard threadprivate objects are to be destroyed in an unspecifed order (p. 152 line 9-10):
The order in which destructors for different threadprivate variables of class type are called is unspecified
The manner of destruction of the objects should be the same as that of static objects (p.151, lines 7-9):
The storage of all copies of a threadprivate variable is freed according to how static variables are handled in the base language, but at an unspecified point in the program.
However, it appears that the objects' destructors are not being called. Based on this link, I've added an explicit barrier (doesn't help). I also set the lifetime of the threads to zero to make sure they don't outlive the master thread as well as adding some busy work after the last parallel region.
Here's the (roughly) minimal example:
#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 from "<< _n << "\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; }
I would expect 4 (on my machine) "bye bye" messages, whereas I only see one.