En Visual Studio, no se llama al destructor de `thread_local` variables 'cuando se usa con std :: async, ¿es esto un error?
El siguiente código
#include <iostream>
#include <future>
#include <thread>
#include <mutex>
std::mutex m;
struct Foo {
Foo() {
std::unique_lock<std::mutex> lock{m};
std::cout <<"Foo Created in thread " <<std::this_thread::get_id() <<"\n";
}
~Foo() {
std::unique_lock<std::mutex> lock{m};
std::cout <<"Foo Deleted in thread " <<std::this_thread::get_id() <<"\n";
}
void proveMyExistance() {
std::unique_lock<std::mutex> lock{m};
std::cout <<"Foo this = " << this <<"\n";
}
};
int threadFunc() {
static thread_local Foo some_thread_var;
// Prove the variable initialized
some_thread_var.proveMyExistance();
// The thread runs for some time
std::this_thread::sleep_for(std::chrono::milliseconds{100});
return 1;
}
int main() {
auto a1 = std::async(std::launch::async, threadFunc);
auto a2 = std::async(std::launch::async, threadFunc);
auto a3 = std::async(std::launch::async, threadFunc);
a1.wait();
a2.wait();
a3.wait();
std::this_thread::sleep_for(std::chrono::milliseconds{1000});
return 0;
}
Compilado y ejecutar ancho de clang en macOS:
clang++ test.cpp -std=c++14 -pthread
./a.out
Got result
Foo Created in thread 0x70000d9f2000
Foo Created in thread 0x70000daf8000
Foo Created in thread 0x70000da75000
Foo this = 0x7fd871d00000
Foo this = 0x7fd871c02af0
Foo this = 0x7fd871e00000
Foo Deleted in thread 0x70000daf8000
Foo Deleted in thread 0x70000da75000
Foo Deleted in thread 0x70000d9f2000
Compilado y ejecutado en Visual Studio 2015 Actualización 3:
Foo Created in thread 7180
Foo this = 00000223B3344120
Foo Created in thread 8712
Foo this = 00000223B3346750
Foo Created in thread 11220
Foo this = 00000223B3347E60
Destructor no se llama.
Es esto un error o una zona gris indefinida?
PD
Si el sueñostd::this_thread::sleep_for(std::chrono::milliseconds{1000});
al final no es lo suficientemente largo, es posible que a veces no veas los 3 mensajes "Eliminar".
Cuando usasstd::thread
en lugar destd::async
, se llama a los destructores en ambas plataformas, y los 3 mensajes "Eliminar" siempre se imprimirán.