- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider a variation on this:
class myclass { static volatile int _refcnt = 0; static myclass* _p = NULL; int _n; public: myclass(int n) : _n(n) { if(_p==NULL) { _p = this; _refcnt = 1; } else { #pragma omp atomic ++_refcnt; } std::cout << "int c'tor\n"; } myclass() : _n(0) { if(_p==NULL) { _p = this; _refcnt = 1; } else { #pragma omp atomic ++_refcnt; } std::cout << "def c'tor\n"; } myclass(const myclass & other) : _n(other._n) { std::cout << "copy c'tor\n"; } ~myclass() { if(_p == this) { while(_refcnt > 1) sleep(0); } #pragma omp atomic --_refcnt; std::cout << "bye bye from " << _n << "\n"; } void print() { std::cout << _n << "\n"; } void add(int t) { _n += t; } };
(untested)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In your case, none of the four objects are properly disposed. The main threads instances destructor (_p == this) is called, but because _refcnt is equal to the number of threads it never passes the while loop. The other threads don't call the destructor for their objects and therefore _refcnt is never decremented. The end result is that the program never exits. The issue remains the same.
(tested)
Avi
jimdempseyatthecove wrote:
Consider a variation on this:
class myclass { static volatile int _refcnt = 0; static myclass* _p = NULL; int _n; public: myclass(int n) : _n(n) { if(_p==NULL) { _p = this; _refcnt = 1; } else { #pragma omp atomic ++_refcnt; } std::cout << "int c'tor\n"; } myclass() : _n(0) { if(_p==NULL) { _p = this; _refcnt = 1; } else { #pragma omp atomic ++_refcnt; } std::cout << "def c'tor\n"; } myclass(const myclass & other) : _n(other._n) { std::cout << "copy c'tor\n"; } ~myclass() { if(_p == this) { while(_refcnt > 1) sleep(0); } #pragma omp atomic --_refcnt; std::cout << "bye bye from " << _n << "\n"; } void print() { std::cout << _n << "\n"; } void add(int t) { _n += t; } };(untested)
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page