In the question Using QSqlQuery from multiple threads there was the outcome that thread storage solves the problem.
I made a simple demo code to be absolutely clear about C++11 thread_local specifier. The code below creates two threads which have ThreadLocal object as a local unique object. The Storage::get function is a thread specific singleton. Does the standard guarantee that ThreadLocal destructor is called on join or the exit of the thread function?
Compiled with GCC 5.4.0
(g++ -o main main.cpp --std=c++11 -lpthread)
#include <thread>
#include <mutex>
#include <string>
#include <chrono>
#include <iostream>
#include <atomic>
static std::mutex mtx;
struct ThreadLocal {
std::string name;
~ThreadLocal() {
mtx.lock();
std::cout << "destroy " << name << std::endl;
mtx.unlock();
}
};
struct Storage {
static ThreadLocal &get() {
/* Thread local singleton */
static thread_local ThreadLocal l;
static std::atomic<int> cnt(0);
l.name = std::to_string(cnt);
cnt++;
return l;
}
};
void thread() {
mtx.lock();
std::cout << Storage::get().name << std::endl;
mtx.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main(int argc, const char **argv) {
std::thread t1(&thread);
std::thread t2(&thread);
t1.join();
t2.join();
}
If the object was constructed, it will be destroyed on the exit of the thread function. Pretty much in those exact words over at [basic.stc.thread]/2:
A variable with thread storage duration shall be initialized before
its first odr-use ([basic.def.odr]) and, if constructed, shall be
destroyed on thread exit.
Related
If I create a thread_local object, its destructor is called on the thread it was created on:
#include <iostream>
#include <thread>
#include <chrono>
struct MyStruct {
~MyStruct() {
std::cout << "Destructed on thread #" << std::this_thread::get_id() << std::endl;
}
};
void f() {
thread_local MyStruct myStruct;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main() {
std::thread t(f);
std::cout << "Created thread #" << t.get_id() << std::endl;
t.join();
}
Created thread #16920
Destructed on thread #16920
Does the C++ standard guarantee this behaviour? It only states this:
A variable with thread storage duration shall be initialized before
its first odr-use (6.2) and, if constructed, shall be destroyed on
thread exit.
I am analyzing a crash dump and found that I have a race condition in the local static object initialization. I am using MSVC++12.0 which doesn't have a thread safe static initialization.
Here is the minimal version of the program.
#include <iostream>
#include <thread>
#include <chrono>
#include <Windows.h>
class internalClass
{
public:
internalClass(int parm) : value(parm) {}
int value;
};
class externalClass
{
public:
externalClass(int parm)
{
Sleep(1000*10);
dp = new internalClass(parm);
}
void print()
{
std::cout << dp->value << "\n";
}
~externalClass()
{
delete dp;
}
internalClass *dp;
};
static void foo()
{
static externalClass obj(50);
obj.print();
}
int main()
{
std::thread t1(foo);
Sleep(1000);
std::thread t2(foo);
t1.join();
t2.join();
}
In the main program, externalClass is actually used for resource synchronization.
I need to hold std::mutex for every object that I create to use later.
I am aware of that std::mutex is non-copyable non-movable.
Also I have looked at this:
map-of-mutex-c11
What I do is, create a std::map with objectID(key) and objectInfo*
, and have the mutex in objectInfo.
So, as what I store in the map is a pointer to some structure, I do not see any problem about std::mutex, which would have occured if I had, let say, std::map<int, std::mutex>.
However, it seems that the code I have written has some problem. After inserting the code with mutexes, I get sometimes segfault when I do std::unique_lock::try_lock.
Here is minimized version of the code that I inserted in huge project:
// Example program
#include <iostream>
#include <string>
#include <mutex>
#include <map>
#include <thread>
struct sObjectInfo {
std::mutex mut;
};
std::map<int, sObjectInfo*> mymap;
void foo() {
std::unique_lock<std::mutex> ulock(mymap[0]->mut, std::defer_lock);
if (ulock.try_lock()) {
std::cout << "locked.." << std::endl;
}
else {
std::cout << "cant lock" << std::endl;
}
}
int main()
{
sObjectInfo* s1 = new sObjectInfo();
sObjectInfo* s2 = new sObjectInfo();
mymap[0] = s1;
mymap[1] = s2;
std::thread t1(foo);
t1.join();
}
Here is the live example:
ideone
What is wrong with the use of mutexes in this example?
Is it good or bad to create a thread in function object constructor by passing the dereferenced this pointer by reference to the thread object?
Is there any problem in below code?
Any improvement can be made on it to reach below objective?
The objective is to gracefully end the thread when the class object is out of scope.
#include <iostream>
#include <chrono>
#include <future>
#include <thread>
class MyThread {
private:
std::atomic<bool> exit;
std::thread t;
public:
MyThread() : exit(false) {
t = std::thread(std::ref(*this));
}
~MyThread() {
exit.store(true, std::memory_order_relaxed);
if (t.joinable()) {
t.join();
}
}
void operator()() {
while (!exit.load(std::memory_order_relaxed)) {
std::cout << "."; // some more meaningful work here
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
};
int main() {
MyThread t;
std::cin.get();
return 0;
}
It might work occasionally, but it's unsafe. It potentially generates a race condition, because you start the thread on an object that hasn't finished its construction yet, resulting in undefined behavior.
I have a std::thread waiting and reading from a socket. And there is a pointer to this thread stored somewhere. But when something bad happens and the thread ends, I want it to call something that results in a function that will join this thread and then delete the pointer referring to it. (I have access to that pointer from within the thread)
I could do that in another thread but then that new thread becomes the problem.
You could create your thread in a detached state, and make your thread lifetime dependent a condition variable and switch a boolean state on finish.
#include <thread>
#include <iostream>
#include <unistd.h>
#include <condition_variable>
#include <mutex>
class A {
private:
void Threadfunction();
volatile bool class_running;
volatile bool thread_running;
std::condition_variable cv;
std::mutex mu;
public:
A();
~A();
void Stop();
};
A::A(){
class_running = true;
thread_running = false;
std::thread t(&A::Threadfunction,this);
t.detach();
}
A::~A(){
if(class_running) {this->Stop();}
}
void A::Stop() {
std::unique_lock<std::mutex> lk(mu);
class_running = false;
while(thread_running) {
cv.wait(lk);
}
std::cout << "Stop ended " << std::endl;
}
void A::Threadfunction(){
thread_running = true;
std::cout << "thread started " << std::endl;
while(class_running){
// Do something
}
thread_running = false;
cv.notify_one();
std::cout << "thread stopped " << std::endl;
}
int main(){
A a1;
A a2;
sleep(1);
std::cout << "a1.Stop() called " << std::endl;
a1.Stop();
sleep(1);
std::cout << "a2.Stop() not called but a2 goes out of scope and destructor is called " << std::endl;
}
Change your design so that you don't have this bizarre requirement. One simple solution is to use shared_ptrs to a control structure that owns the thread and has other status information as well. The thread can hold a shared_ptr to this control structure and use it to report its status to any other interested code. When nobody cares about this thread anymore, the last shared_ptr to this control structure will go away and it will be destroyed.