I have following code block which gets a lock and perform operations. I don't have any wait() called inside the synchronized block.
Object obj = new Object();
...
someMethod() {
synchronized (obj) {
try {
Some operations but no wait() is there.
} finally {
obj.notify();
}
}
}
As i need some operation which needs locking.
Does calling notify makes any sense? Could there be a case that could hold a lock and not allow other threads to execute? There is no way for the code to get into an infinite loop, but yes an exception might be thrown.
Related
class ThreadOne {
public:
ThreadOne();
void RealThread();
void EnqueueJob(s_info job);
std::queue<s_info> q_jobs;
private:
H5::H5File* targetFile = new H5::H5File("file.h5", H5F_ACC_TRUNC);
std::condition_variable cv_condition;
std::mutex m_job_q_;
};
ThreadOne::ThreadOne() {
}
void ThreadOne::RealThread() {
while (true) {
std::unique_lock<std::mutex> lock(m_job_q_);
cv_condition.wait(lock, [this]() { return !this->q_jobs.empty(); });
s_info info = std::move(q_jobs.front());
q_jobs.pop();
lock.unlock();
//* DO THE JOB *//
}
}
void ThreadOne::EnqueueJob(s_info job) {
{
std::lock_guard<std::mutex> lock(m_job_q_);
q_jobs.push(std::move(job));
}
cv_condition.notify_one();
}
ThreadOne *tWrite = new ThreadOne();
I want to make a thread and send it a pointer of an array and its name as a struct(s_info), and then make the thread write it into a file. I think that it's better than creating a thread whenever writing is needed.
I could make a thread pool and allocate jobs to it, but it's not allowed to write the same file concurrently in my situation, I think that just making a thread will be enough and the program will still do CPU-bound jobs when writing job is in process.
To sum up, this class (hopefully) gets array pointers and their dataset names, puts them in q_jobs and RealThread writes the arrays into a file.
I referred to a C++ thread pool program and the program initiates threads like this:
std::vector<std::thread> vec_worker_threads;
vector_worker_threads.reserve(num_threads_);
vector_worker_threads.emplace_back([this]() { this->RealThread(); });
I'm new to C++ and I understand what the code above does, but I don't know how to initiate RealThread in my class without a vector. How can I make an instance of the class that has a thread(RealThread) that's already ready inside it?
From what I can gather, and as already discussed in the comments, you simply want a std::thread member for ThreadOne:
class ThreadOne {
std::thread thread;
public:
~ThreadOne();
//...
};
//...
ThreadOne::ThreadOne() {
thread = std::thread{RealThread, this};
}
ThreadOne::~ThreadOne() {
// (potentially) notify thread to finish first
if(thread.joinable())
thread.join();
}
//...
ThreadOne tWrite;
Note that I did not start the thread in the member-initializer-list of the constructor in order to avoid the thread accessing other members that have not been initialized yet. (The default constructor of std::thread does not start any thread.)
I also wrote a destructor which will wait for the thread to finish and join it. You must always join threads before destroying the std::thread object attached to it, otherwise your program will call std::terminate and abort.
Finally, I replaced tWrite from being a pointer to being a class type directly. There is probably no reason for you to use dynamic allocation there and even if you have a need for it, you should be using
auto tWrite = std::make_unique<ThreadOne>();
or equivalent, instead, so that you are not going to rely on manually deleteing the pointer at the correct place.
Also note that your current RealThread function seems to never finish. It must return at some point, probably after receiving a notification from the main thread, otherwise thread.join() will wait forever.
I have a class with some methods that should be thread safe, i.e. multiple threads should be able operate on the class object state. One of the methods spawns a new thread that, every 10 seconds, updates a field. Because this thread can be long-running, I'd like to be able to abort it properly.
I have implemented a solution that uses std::condition_variable.wait_for() to wait for an abortion signal inside the thread, but am not particularly sure if my solution is either optimal or correct at all.
class A
{
unsigned int value; // A value that will be updated every 10 s in another thread
bool is_being_updated; // true while value is being updated in another thread
std::thread t;
bool aborted; // true = thread should abort
mutable std::mutex m1;
mutable std::mutex m2;
std::condition_variable cv;
public:
A();
~A();
void begin_update(); // Creates a thread that periodically updates value
void abort(); // Aborts the updating thread
unsigned int get_value() const;
void set_value(unsigned int);
};
This is how I implemented the methods:
A::A() : value(0), is_being_updated(false), aborted(false) { }
A::~A()
{
// Not sure if this is thread safe?
if(t.joinable()) t.join();
}
// Updates this->value every 10 seconds
void A::begin_update()
{
std::lock_guard<std::mutex> lck(m1);
if (is_being_updated) return; // Don't allow begin_update() while updating
is_being_updated = true;
if (aborted) aborted = false;
// Create a thread that will update value periodically
t = std::thread([this] {
std::unique_lock<std::mutex> update_lock(m2);
for(int i=0; i < 10; i++)
{
cv.wait_for(update_lock, std::chrono::seconds(10), [this]{ return aborted; });
if (!aborted)
{
std::lock_guard<std::mutex> lck(m1);
this->value++; // Update value
}
else
{
break; // Break on thread abort
}
}
// Locking here would cause indefinite blocking ...
// std::lock_guard<std::mutex> lck(m1);
if(is_being_updated) is_being_updated = false;
});
}
// Aborts the thread created in begin_update()
void A::abort()
{
std::lock_guard<std::mutex> lck(m1);
is_being_updated = false;
this->value = 0; // Reset value
{
std::lock_guard<std::mutex> update_lock(m2);
aborted = true;
}
cv.notify_one(); // Signal abort ...
if(t.joinable()) t.join(); // Wait for the thread to finish
}
unsigned int A::get_value() const
{
std::lock_guard<std::mutex> lck(m1);
return this->value;
}
void A::set_value(unsigned int v)
{
std::lock_guard<std::mutex> lck(m1);
if (is_being_updated) return; // Cannot set value while thread is updating it
this->value = v;
}
This seems to work fine, but I'm uncertain about it being correct. My concerns are the following:
Is my destructor safe? Suppose that the updating thread has not been aborted and is still doing its job while A object goes out of scope. A switch to a different thread now happens while dtor's t.join() still hasn't finished, and the switched-to thread calls begin_update() on the same object. Is something like this possible? Should I introduce e.g. an extra is_being_destructed flag that I would set to true inside a destructor and that all other methods should check for being false before they can proceed? Or can no such undesired scenario happen?
Inside the thread, at the end, I'm setting is_being_updated = false without a lock, despite the variable being shared state. This can mean that other threads won't see its correct value, e.g. even after the thread is done, some other thread may still see the value as is_being_updated == true instead of false. I cannot lock the mutex, however, because abort() may have already locked it, meaning that the call will block indefinitely. I'm not sure about the best way to solve this, other than perhaps making is_being_updated atomic. Would that work?
I've read about spurious wakeups, but am not sure I the code should do anything extra to handle them. As far as I understand, the answer is no, and no problems are to be expected in this regard.
Is my thinking here correct? Did I miss anything else that I should have in mind?
This stuff is always hard to check, so don't be afraid to question me if you think I misunderstand.
Short answer, no, it's not thread safe.
As long as the thread that has scope of A is the one calling abort (and doesn't forget to call abort), you won't experience a race condition, as A::abort() will block until the thread is joined. Under these assumptions, the join in your destructor is pointless.
If abort is called by the a thread that doesn't own A, then it's definitely possible for the thread to be join-ed twice, which is bad. Using .joinable() to decide to join a thread or not is a big red flag.
Please remove one of your if(t.joinable()) t.join(); (I'm leaning towards the one in the destructor) and change the other to just t.join().
As you said, you can make is_being_updated atomic. That's a great solution.
Here's another solution. You can signal without holding the lock. (It's actually better form in general, as it helps reduce lock contention, since the first thing the woken thread needs to do is reacquire its mutex.)
void A::abort()
{
{
std::lock(m1, m2); // deadlock-proof
std::lock_guard<std::mutex> lck(m1, std::adopt_lock);
std::lock_guard<std::mutex> update_lock(m2, std::adopt_lock);
is_being_updated = false;
this->value = 0; // Reset value
aborted = true;
}
cv.notify_one(); // Signal abort ...
t.join(); // Wait for the thread to finish
}
You're good. The way you wrote the wait, you will only come back if abort==true or 10 seconds has elapsed.
1) I think this problem is inherent on your design, as it is a bool flag will not fix the problem. Maybe A shouldn't go out of scope until all the threads stop using it, in which case it should reside in a managed pointer like shared_ptr.
2) You should be using atomics for your bools and also value, this would avoid having to use the unique_lock for increasing the value and for returning it.
3) As I said in the comments the lambda in the cv handles the spurious wakeups.
The biggest bit of code smell is using a full thread to update a variable every 10 seconds. A heavy-weight OS thread with magabytes to gigabytes of address space to do one task every 10 seconds.
What more, it is updating a value without anyone being able to see the change.
You already have a get_value wrapping accessor. Simply store the start point when you want to start counting. When you call get_value calculate the time since the start point. Divide by 10 seconds. Use that to calculate the returned value.
In a real application, you'd have a timer system that lets you trigger events (either in a thread pool, or in a message pump) every period of time. You'd use that instead of a dedicated thread to do something like this, and you'd make sure that modifying that value was vulgar (allowed people to subscribe to changes in it). Then your abort would consist of deregistering the timer instead of stopping a thread.
Your system is a horrible mixture of the two, using threads for no good reason.
I'm using pthread_mutex_t for locking.
pthread_mutex_t m_lock;
void get1() {
cout<<"Start get 1"<<endl;
pthread_mutex_lock(&m_lock);
get2();
pthread_mutex_unlock(&m_lock);
cout<<"End get 1"<<endl;
}
void get2() {
cout<<"Start get 2"<<endl;
pthread_mutex_lock(&m_lock); // The program actually stops here because it waits to m_lock to be unlock from get1 function.
pthread_mutex_unlock(&m_lock);
cout<<"End get 2"<<endl;
}
// The thread call to run function
void* run(void* p) {
get1();
}
Lets say I have only one thread that calls to run function, so:
get1 lock the m_lock and call to get2, but when it tries to lock m_lock, it waits that the lock will be unlock (something that not happen) and we got a deadlock.
My question is how can I avoid this case when the same thread that locked the lock in get1, will not need to wait for the lock in get2 (because it is the same thread)?
For example, in Java this case never can happen when you use synchornized.
public Test implements Runnable {
public void get1() {
System.out.println("Start get 1");
synchronized (this) {
get2();
}
System.out.println("End get 1");
}
public void get2() {
System.out.println("Start get 2");
synchronized (this) {
}
System.out.println("End get 2");
}
#Override
public void run() {
get1();
}
}
No deadlock here.
I want the same result in my C code please.
Thanks.
As noted by Kami Kaze in the comments, if this is your full example, then it's a non-issue: there's only one path leading to get2, and this path already acquires the mutex; simply omit acquiring it a second time.
However, in general, it's possible to think of scenarios where it's not that clear. In this case, you can make the mutex recursive/reentrant:
In computer science, the reentrant mutex (recursive mutex, recursive lock) is particular type of mutual exclusion (mutex) device that may be locked multiple times by the same process/thread, without causing a deadlock.
In your settings, this would be via pthread_mutexattr_settype:
pthread_mutexattr_settype(&m_lock, PTHREAD_MUTEX_RECURSIVE);
This is called lock recursion.
The last argument to pthread_mutex_init is an attributes struct. You can set the attributes to allow recursive locking with pthread_mutexattr_settype(..., PTHREAD_MUTEX_RECURSIVE).
But, I must add some editorial content here. I believe very strongly that lock recursion is almost always a bug. Or it will lead to impossible to debug bugs later in the programs life time.
A locking operation can be reasoned to mean "when the lock function returns the object protected by the lock is in a known state and this state will not change until the unlock function is called". This means that if get1 has started to modify the object you protect with the lock and then get2 recurses that lock, this contract is broken twice. First because get2 succeeds obtaining the lock while the object is not in a known state, second because the object is modified while get1 thinks it owns the lock.
Sure, we often get away with doing things like this but it is a terrible practice. Redesign your program to not recurse locks. The standard way to do this would be to implement a function called get2_locked and get2 obtains the lock and calls get2_locked while get1 already knows it has the lock and would call get2_locked.
With this:
pthread_mutex_lock(&m_lock);
get2();
pthread_mutex_unlock(&m_lock);
you have locked the entire get2(). So, there's no point in taking the same lock again inside get2() function.
Just remove the locking and unlocking code from get2().
If only the code part in get2() requires a locking then get rid of the locking and unlocking from get1() function.
For example, in Java this case never can happen when you use
synchornized.
In your code there the synchronized regions are not interlinked. So, for a similar comparison, you need to use a different mutex in get2() function.
I assume that get1 really does more than just acquire the lock and call get2? Otherwise what is the point of get1?
If that's the case you could solve it by having a get3 function which does the main part of get2 (the part you don't show here) and which doesn't lock. Then call that new function from get1 instead (and of course from get too):
void get1()
{
// Do something here
cout<<"Start get 1"<<endl;
pthread_mutex_lock(&m_lock);
get3(); // <-- Note call get3 instead here
pthread_mutex_unlock(&m_lock);
cout<<"End get 1"<<endl;
// Do something more here
}
void get2()
{
cout<<"Start get 2"<<endl;
pthread_mutex_lock(&m_lock); // The program actually stops here because it waits to m_lock to be unlock from get1 function.
get3(); // <-- Note call to get3 here
pthread_mutex_unlock(&m_lock);
cout<<"End get 2"<<endl;
}
void get3()
{
// Do the actual work of get2 here...
// Note: No locking here
}
I'm refactoring some time consuming function so that it can be called from a thread, but I'm having trouble wrapping my head around the issue (not very familiar with thread programming).
At any point, the user can cancel and the function will stop. I do not want to kill the thread as soon as the user cancels since it could cause some data integrity problems. Instead, in several places in the function, I will check if the function has been cancelled and, if so, exit. I will only do that where I know it's safe to exit.
The whole code of the function will be within a mutex. This is the pseudo-code I have in mind:
SomeClass::SomeClass() {
cancelled_ = false;
}
void SomeClass::cancelBigSearch() {
cancelled_ = true;
}
void SomeClass::bigSearch() {
mutex.lock();
// ...
// Some code
// ...
// Safe to exit at this point
if (cancelled_) {
mutex.unlock();
cancelled_ = false;
return;
}
// ...
// Some more code
// ...
if (cancelled_) {
mutex.unlock();
cancelled_ = false;
return;
}
// ...
// Again more code
// ...
if (cancelled_) {
mutex.unlock();
cancelled_ = false;
return;
}
mutex.unlock();
}
So when the user starts a search, a new thread calls bigSearch(). If the user cancels, cancelBigSearch() is called and a cancelled_ flag is set. Then, when bigSearch() reaches a point where it's safe to exit, it will exit.
Any idea if this is all thread-safe?
You should lock access to cancelled_ with another mutex, so checking and setting does not happen simultaneously. Other than that, I think your approach is OK
Update: Also, make sure no exceptions can be thrown from SomeClass::bigSearch(), otherwise the mutex might remain in a locked state. To make sure that all return paths unlock the mutex, you might want to surround the processing parts of the code with if (!cancelled_) and return only at the very end of the method (where you have the one unlock() call on the mutex.
Better yet, wrap the mutex in a RAII (acronym for Resource Allocation Is Initialization) object, so no matter how the function ends (exception or otherwise), the mutex is guaranteed to be unlocked.
Yes, this is thread safe. But:
Processors can have separate cache and cache it's own copy of cancelled_, typically mutex synchronization functions applies proper cache synchronization.
Compiler generated code, can make invalid assumptions about Your data locality, this can lead to not update in time cancelled_. Some platform specific commands can help here, or you can simply use other mechanisms.
All these lead to a thread that isn't canceled in time as you wish.
Your code usage pattern is simple "signaling". So you need to transfer signal to thread. Signal patterns allows trigger multiple times same trigger (signal), and clear it later.
This can be simulated using:
atomic operations
mutex protected variables
signal synchronization primitives
It's not thread-safe, because one thread could read cancelled_ at the same time another thread writes to it, which is a data race, which is undefined behaviour.
As others suggested, either use an atomic type for cancelled_ or protect it with another mutex.
You should also use RAII types to lock the mutexes.
e.g.
void SomeClass::cancelBigSearch() {
std::lock_guard<std::mutex> lock(cxlMutex_);
cancelled_ = true;
}
bool SomeClass::cancelled() {
std::lock_guard<std::mutex> lock(cxlMutex_);
if (cancelled_) {
// reset to false, to avoid caller having to lock mutex again to reset it
cancelled_ = false;
return true;
}
return false;
}
void SomeClass::bigSearch() {
std::lock_guard<std::mutex> lock(mutex);
// ...
// Some code
// ...
// Safe to exit at this point
if (cancelled())
return;
// ...
// Some more code
// ...
if (cancelled())
return;
// ...
// Again more code
// ...
if (cancelled())
return;
}
I am using boost library for threading and synchronization in my application.
First of all I must say exceptions within threads on synchronization is compilitey new thing for me.
In any case below is the pseudo code what I want to achieve. I want synchronized threads to throw same exception that MAY have been thrown from the thread doing notify. How can I achieve this?
Could not find any topics from Stack Overflow regarding exception throwing with cross thread interaction using boost threading model
Many thanks in advance!
// mutex and scondition variable for the problem
mutable boost::mutex conditionMutex;
mutable boost::condition_variable condition;
inline void doTheThing() const {
if (noone doing the thing) {
try {
doIt()
// I succeeded
failed = false;
condition.notify_all();
}
catch (...) {
// I failed to do it
failed = true;
condition.notify_all();
throw
}
else {
boost::mutex::scoped_lock lock(conditionMutex);
condition.wait(lock);
if (failed) {
// throw the same exception that was thrown from
// thread doing notify_all
}
}
}
So you want the first thread that hits doTheThing() to call doIt(), and all subsequent threads that hit doTheThing() to wait for the first thread to finish calling doIt() before they proceed.
I think this should do the trick:
boost::mutex conditionMutex; // mutable qualifier not needed
bool failed = false;
bool done = false;
inline void doTheThing() const {
boost::unique_lock uql(conditionMutex);
if (!done) {
done = true;
try {
doIt();
failed = false;
}
catch (...) {
failed = true;
throw
}
}
else if (failed)
{
uql.unlock();
// now this thread knows that another thread called doIt() and an exception
// was thrown in that thread.
}
}
Important notes:
Every thread that calls doTheThing() must take a lock. There is no way around this. You are synchronizing threads, and for a thread to know anything about what's happening in another thread, it must take a lock. (Or it can use atomic memory operations, but that's a more advanced technique.) The variables failed and done are protected by the conditionMutex.
C++ will call destructor of uql when the function exits normally or by throwing exception.
EDIT Oh, and as for throwing the exception to all the other threads, forget about that, it's almost impossible, and it isn't the way things are done in C++. Instead, each thread can check to see if the first thread successfully called doIt() in the place I've indicated above.
EDIT There is no language support for propagating an exception to another thread. You can generalize the problem of propagating exceptions to another thread to passing messages to another thread. There are lots of library solutions to the problem of passing messages between threads ( boost::asio::io_service::post() ), and you could pass a message that contains the exception, with instructions to throw that exception on receipt of message. It's a bad idea, though. Only throw exceptions when you have an error that prevents you from unwinding the call stack by ordinary function return. That's what an exception is--an alternative way to return from a function when returning the usual way doesn't make sense.