Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
172 views
in Technique[技术] by (71.8m points)

c++ - deallocation order of the static member and detached thread itself

There is a global function that initializes and cleans up some resources.
But those 2 function must be called when no other thread is running.(like curl_global_init)
Initializer must be manually called, but I don't want the cleaner to be called manually.
So I do the following.

class GLOBAL_WRAPPER {
 public:
  static void init() {
    getInstance();
  }

  static GLOBAL_WRAPPER& getInstance() {
    static GLOBAL_WRAPPER inst;
    return inst;
  }

 private:
  GLOBAL_WRAPPER() {
    // do global init call
  }
  ~GLOBAL_WRAPPER() {
    // do global cleanup call
  }
};

void GLOBAL_INIT() {
  GLOBAL_WRAPPER::init();
}



int main(){
  GLOBAL_INIT();

  // do whatever you want

  // std::thread([](){for(;;);}).detach(); oops!
}

But in such bad case like: creating detached thread and not terminating it before main ends, when is deallocation of static variables(GLOBAL_WRAPPER in this case) called?

  1. detached thread is terminated and static variable is freed
  2. static variable is freed and detached thread is terminated
  3. implementation defined.

I'm just interested in the thread itself, not thread storage duration objects.

question from:https://stackoverflow.com/questions/65838228/deallocation-order-of-the-static-member-and-detached-thread-itself

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The C++ standard specifies (in so many words) that returning from main is equivalent to calling std::exit.

main function [basic.start.main]

A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0.

exit is defined as follows (irrelevant details omitted):

Startup and termination [support.start.term]

[[noreturn]] void exit(int status);

Effects:

— First, objects with thread storage duration and associated with the current thread are destroyed. Next, objects with static storage duration are destroyed and functions registered by calling atexit are called.

— Next, all open C streams ... are removed.

— Finally, control is returned to the host environment. If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If status is EXIT_- FAILURE, an implementation-defined form of the status unsuccessful termination is returned.

It is not defined what happens if non-main execution threads are running when the main execution thread returns. The shown code does not guarantee that the non-main execution thread terminates/sequenced before main returns.

As such, the only thing the standard specifies is that:

  1. Global objects get destroyed

  2. "Control is returned to the host environment", a.k.a.: "It's dead, Jim".

The standard does not define what happens if non-main execution threads are running when the main execution thread returns. A.k.a.: undefined behavior.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...