#include "stdafx.h" #include <iostream> //#include <Windows.h> #include <mutex> //-------------------------------------------------------------------------- std::mutex g_mutex; //-------------------------------------------------------------------------- struct _Int { _Int() { std::cout << "constructor" << std::endl; } _Int(const _Int&) { std::cout << "copy constructor" << std::endl; } _Int(_Int&&) = delete; ~_Int() { std::cout << "destructor" << std::endl; } int m_i { 42 }; }; //-------------------------------------------------------------------------- void _print(_Int i) { std::cout << i.m_i << std::endl; } //-------------------------------------------------------------------------- void worker2(void* param) { std::lock_guard<std::mutex> lock(g_mutex); std::cout << "worker 2" << std::endl; std::function<void(void)>* lambda = (std::function<void(void)>*)param; (*lambda)(); } //-------------------------------------------------------------------------- void worker() { std::lock_guard<std::mutex> lock(g_mutex); std::cout << "worker 1" << std::endl; _Int y; std::function<void(void)>* lambda = new std::function<void(void)>{[=]() { _print(y); }}; std::thread thread(worker2, lambda); thread.detach(); } //-------------------------------------------------------------------------- int main() { std::thread _thread(worker); _thread.detach(); system("pause"); } 

Conclusion:

 worker 1 constructor copy constructor copy constructor destructor destructor worker 2 copy constructor 42 destructor Для продолТСния Π½Π°ΠΆΠΌΠΈΡ‚Π΅ Π»ΡŽΠ±ΡƒΡŽ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ . . . 

Question: In the output we see 4 constructors and only 3 destructors, where did the 4th go? Also, why is the copy constructor called twice?

Example output for capturing by reference:

 worker 1 constructor destructor worker 2 copy constructor 42 destructor Для продолТСния Π½Π°ΠΆΠΌΠΈΡ‚Π΅ Π»ΡŽΠ±ΡƒΡŽ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ . . . 

The code with the capture of the link is invalid, but the balance of designers is respected.

I would be grateful for the link to reading matter, where the life time of variables in lambdas, flows, with capture by value and reference is described in detail.

PS new without delete is made specifically so that the lambda object is alive after the worker () thread has finished

  • one
    In short, the capture of variables in lambda by reference to the lifetime of the variables does not affect. Well, even for new std::function there is no delete . And it is strange to see such a wild mixture of C ++ and WinAPI. If std::function and std::mutex , then why not take std::thread ? - VTT
  • @VTT, yes it can be seen from the second conclusion, and by the designers will help you understand what is happening? - goldstar_labs
  • @VTT, new without delete is made intentionally so that std :: function will live after the worker has finished. Vinapi removed. - goldstar_labs
  • 2
    "new without delete is made intentionally" - well, what's the point then asking where did 4 destructor go? Make a normal join for each thread, delete all objects, and then it will be possible to argue about something. - VTT
  • @VTT, you are right as always) if you add delete to the second thread, then destructors are fine. Thanks - goldstar_labs 1:01

0