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?
Related
I have a class that runs a loop on a seperate thread and I want it to break when I change the value of a member to false:
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <functional>
#include <atomic>
class A
{
public:
void ChangeLoop(){
loop = !loop;
if(loop){
std::future<void> fi = std::async(std::launch::async, &A::RunLoop, this, std::ref(loop));
}
}
void RunLoop(std::atomic<bool> &loop_ref){
while(loop_ref){
emit(loop_ref);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
private:
std::atomic<bool> loop {false};
std::mutex emit_mutex;
template<class...Ts> void emit(Ts&&...ts){
auto lock = std::unique_lock<std::mutex>(emit_mutex);
using expand = int[];
void(expand{
0,
((std::cout << ts << "\n"), 0)...
});
}
};
int main(){
A a;
a.ChangeLoop();
std::this_thread::sleep_for(std::chrono::seconds(2));
a.ChangeLoop();
return 0;
}
When I change loop to false, the thread does not break as I would expect. Alternatively, I tried to have the threaded function look at the member variable without taking any arguments, but had the same issue:
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <functional>
#include <atomic>
class A
{
public:
void ChangeLoop(){
loop = !loop;
if(loop){
std::future<void> fi = std::async(std::launch::async, &A::RunLoop, this);
}
}
void RunLoop(){
while(loop){
emit(loop);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
private:
std::atomic<bool> loop {false};
std::mutex emit_mutex;
template<class...Ts> void emit(Ts&&...ts){
auto lock = std::unique_lock<std::mutex>(emit_mutex);
using expand = int[];
void(expand{
0,
((std::cout << ts << "\n"), 0)...
});
}
};
int main(){
A a;
a.ChangeLoop();
std::this_thread::sleep_for(std::chrono::seconds(2));
a.ChangeLoop();
return 0;
}
How can I thread my RunLoop function seperately, and have it break when I change member variable loop?
As you have already found the working solution to your problem, I just want to point out why std::async is the not the right choice here.
From the online reference on std::async:
If the std::future obtained from std::async is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes.
So what you have here is the destructor of std::future blocking because the thread with RunLoop never completes execution because of its while loop.
This is true even when the return value from std::async is ignored in ChangeLoop and not assigned to a std::future.
Some C++ experts say that an std::future produced by std::async should not block. Here is an article by Herb Sutter where he argues this.
But for now the solution proposed in the comment (of using std::detach) is the way to go.
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.
I encountered some problem and I'm not sure how to deal with it.
#include <iostream>
#include <thread>
#include <condition_variable>
#include <chrono>
std::condition_variable CV;
std::mutex m;
std::size_t i{0};
void set_value() try
{
std::this_thread::sleep_for(std::chrono::seconds{2});
{
std::lock_guard<std::mutex> lock{m};
i = 20;
}
CV.notify_one();
}
catch(...){
//what to do?
}
int main()
{
std::thread t{set_value};
t.detach();
std::unique_lock<std::mutex> lock{m};
CV.wait(lock, []{ return i != 0; });
std::cout << "i has changed to " << i << std::endl;
}
This of course works fine but how should I handle the case when std::lock_guard::lock throws an exception?
At first I was thinking to create global std::atomic<bool> mutex_lock_throwed{ false }; that I could set to true inside the catch block. Than I could notify_one()
catch(...){
mutex_lock_throwed.store(true);
CV.notify_one();
}
and change predicate for wait function to
[]{ return i != 0 || mutex_lock_throwed.load(); }
This actually worked very well but I read this in cppreference
Even if the shared variable is atomic, it must be modified under the mutex in order to correctly publish the modification to the waiting thread.
As you can see its not possible if mutex throws. So what should be the correct way to handle this?
I wrote this sample program to mimic what I'm trying to do in a larger program.
I have some data that will come from the user and be passed into a thread for some processing. I am using mutexes around the data the flags to signal when there is data.
Using the lambda expression, is a pointer to *this send to the thread? I seem to be getting the behavior I expect in the cout statement.
Are the mutexes used properly around the data?
Is putting the atomics and mutexes as a private member of the class a good move?
foo.h
#pragma once
#include <atomic>
#include <thread>
#include <vector>
#include <mutex>
class Foo
{
public:
Foo();
~Foo();
void StartThread();
void StopThread();
void SendData();
private:
std::atomic<bool> dataFlag;
std::atomic<bool> runBar;
void bar();
std::thread t1;
std::vector<int> data;
std::mutex mx;
};
foo.c
#include "FooClass.h"
#include <thread>
#include <string>
#include <iostream>
Foo::Foo()
{
dataFlag = false;
}
Foo::~Foo()
{
StopThread();
}
void Foo::StartThread()
{
runBar = true;
t1 = std::thread([=] {bar(); });
return;
}
void Foo::StopThread()
{
runBar = false;
if(t1.joinable())
t1.join();
return;
}
void Foo::SendData()
{
mx.lock();
for (int i = 0; i < 5; ++i) {
data.push_back(i);
}
mx.unlock();
dataFlag = true;
}
void Foo::bar()
{
while (runBar)
{
if(dataFlag)
{
mx.lock();
for(auto it = data.begin(); it < data.end(); ++it)
{
std::cout << *it << '\n';
}
mx.unlock();
dataFlag = false;
}
}
}
main.cpp
#include "FooClass.h"
#include <iostream>
#include <string>
int main()
{
Foo foo1;
std::cout << "Type anything to end thread" << std::endl;
foo1.StartThread();
foo1.SendData();
// type something to end threads
char a;
std::cin >> a;
foo1.StopThread();
return 0;
}
You ensure that the thread is joined using RAII techniques? Check.
All data access/modification is either protected through atomics or mutexs? Check.
Mutex locking uses std::lock_guard? Nope. Using std::lock_guard wraps your lock() and unlock() calls with RAII. This ensures that even if an exception occurs while within the lock, that the lock is released.
Is putting the atomics and mutexes as a private member of the class a good move?
Its neither good nor bad, but in this scenario, where Foo is a wrapper for a std::thread that does work and controls the synchronization, it makes sense.
Using the lambda expression, is a pointer to *this send to the thread?
Yes, you can also do t1 = std::thread([this]{bar();}); to make it more explicit.
As it stands, with your dataFlag assignments after the locks, you may encounter problems. If you call SendData twice such that bar processes the first one but is halted before setting dataFlag = false so that the second call adds the data, sets the flag to true only to have bar set it back to false. Then, you'll have data that has been "sent" but bar doesn't think there's anything to process.
There may be other tricky situations, but this was just one example; moving it into the lock clears up that problem.
for example, your SendData should look like:
void Foo::SendData()
{
std::lock_guard<std::mutex> guard(mx);
for (int i = 0; i < 5; ++i) {
data.push_back(i);
}
dataFlag = true;
}
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.