I have below code where function bar lock the mutex and then called function foo, however function foo lock the same mutex. according to my understanding, dead-lock will take place because foo are trying to lock the same mutex and it has been locked in function bar. But below code executes without any halt. Who knows the reason??
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void foo()
{
pthread_mutex_lock(&mutex);
cout<<"excuting foo!!"<<endl;
pthread_mutex_unlock(&mutex);
}
void bar()
{
pthread_mutex_lock(&mutex);
cout<<"excuting bar!!"<<endl;
foo();
pthread_mutex_unlock(&mutex);
}
int main()
{
bar();
}
The POSIX thread specification allows a POSIX thread implementation to use any of the standard three mutex types as the default one:
If the mutex type is PTHREAD_MUTEX_DEFAULT, the behavior of
pthread_mutex_lock() may correspond to one of the three other standard
mutex types
What is PTHREAD_MUTEX_DEFAULT? That's pretty much what you expect:
The default value of the type attribute is PTHREAD_MUTEX_DEFAULT.
...
An implementation may map PTHREAD_MUTEX_DEFAULT to one of the other
mutex types.
You are expecting your mutex to be PTHREAD_MUTEX_NORMAL which will cause a deadlock here. However, your particular thread implementation appears to be the PTHREAD_MUTEX_RECURSIVE type, which can be locked more than once by the same process. This is the behavior you are observing.
You need to modify bar() as:
void bar()
{
pthread_mutex_lock(&mutex);
cout<<"excuting bar!!"<<endl;
pthread_mutex_unlock(&mutex);
foo();
}
In your code, deadlock is there because sequence is following
1. bar () locks mutex,
2. Foo() trying to lock mutex again which is already locked by bar
3. bar() unlocks it,but earlier operation step 2, still waiting for mutex. This steps waits for step 2 to finish
Related
Given the following code, Is it guaranteed to see the latest value 4 of a ?
int a;
mutex mtx;
void f() {
unique_lock<mutex> lck(mtx);
// read(a);
// is it guarantee it will see the value 4?
}
int main() {
a = 4;
thread(f);
}
Yes, it is guaranteed:
32.4.2.2 Constructors [thread.thread.constr]
Synchronization: The completion of the invocation of the constructor
synchronizes with the beginning of the invocation of the copy of f.
In other words, the construction of std::thread itself, which occurs in the original execution thread, synchronizes with the beginning of the invocation of the thread function. Or, in other words: everything that happens before std::thread gets constructed, in the original thread, is visible in the thread function.
In the book "Concurrency in Action", there's an implementation of thread-safe stack where mutex is acquired/locked upon entering pop() and empty() functions like shown below:
class threadsafe_stack {
private:
std::stack<T> data;
mutable std::mutex m;
public:
//...
void pop(T& value) {
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
value = std::move(data.top());
data.pop();
}
bool empty() const {
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
};
My question is, how does this code not run into a deadlock, when a thread, that has acquired the lock upon entering pop() is calling empty() which is protected by mutex as well? If lock() is called by the thread that already owns the mutex, isn't that undefined behavior?
how does this code not run into a deadlock, when a thread, that has acquired the lock upon entering pop() is calling empty() which is protected by mutex as well?
Because you are not calling empty member function of threadsafe_stack but you are calling empty() of class std::stack<T>. If the code would be:
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(empty()) // instead of data.empty()
throw empty_stack();
value = std::move(data.top());
data.pop();
}
Then, it would be undefined behavior:
If lock is called by a thread that already owns the mutex, the behavior is undefined: for example, the program may deadlock. An implementation that can detect the invalid usage is encouraged to throw a std::system_error with error condition resource_deadlock_would_occur instead of deadlocking.
Learn about recursive and shared mutex.
Not 100% sure what you mean, I guess you mean calling pop and empty sequentially in the same thread? Like in
while(!x.empty()) x.pop();
std::lock_guard follows RAII. This means the constructor
std::lock_guard<std::mutex> lock(m);
will acquire/lock the mutex and the destructor (when lock goes out of scope) will release/unlock the mutex again. So it's unlocked at the next function call.
Inside pop only data.empty() is called, which is not protected by a mutex. Calling this->empty() inside pop would indeed result in undefined behaviour.
You would be correct if pop would call this->empty. Locking the same mutex twice via a std::lock_guard is undefined behavior unless the locked mutex is a recursive one.
From cppreference on the constructor (the one that is used in the example code):
Effectively calls m.lock(). The behavior is undefined if m is not a recursive mutex and the current thread already owns m.
For the sake of completeness, there is a second constructor:
lock_guard( mutex_type& m, std::adopt_lock_t t );
which
Acquires ownership of the mutex m without attempting to lock it. The behavior is undefined if the current thread does not own m.
However, pop calls data.empty and this is the method of the private member, not the member function empty of threadsafe_stack. There is no problem in the code.
I'm trying to understand std::mutex, std::lock_guard, std::unique_lock better when working with a class.
For starters I sort of know the difference between lock_guard and unique_lock: I know that lock_guard only locks the mutex on construction which is a preferred use when using it in a class member function as such:
class Foo {
std::mutex myMutex;
public:
void someFunc() {
std::lock_guard<std::mutex> guard( myMutex );
// code
}
};
As in the above the lock_guard with the class's member myMutex will be locked in the beginning of the scope of the function Foo::someFunc() then unlocked after the code leaves the scope due to the destructors of both lock_guard and mutex.
I also understand that unique_lock allows you to lock & unlock a mutex multiple times.
My question is about a design of a class to where; what If I want the mutex to be locked in the constructor of the class, then not to have it unlock when the constructor goes out of scope, but to unlock when the destructor of the class is called...
class Foo {
std::mutex myMutex;
public:
Foo() {
// lock mutex here;
}
~Foo() {
// unlock mutex here;
}
};
Can the above be achieved; and if so how?
In the last example above what I'm not sure about is: if a lock_guard is used in the constructor of the class; will it go out of scope after the constructor leaves scope, or when the class's destructor is invoked when the object of the class goes out of scope? I like to try to mimic the desired behavior of the 2nd example shown.
After I had posted this question: I did a little more research and some trial and errors. With that I have opted towards a different implementation and solution.
Instead of what I was originally proposing, I ended up using std::shared_mutex and std:shared_lock.
So in my class's header I'm not saving or storing any mutex. Now in my class's cpp file. I'm using a static global shared_mutex
So my class now looks like this:
Foo.cpp
#include "Foo.h"
#include <mutex>
std::mutex g_mutex;
Foo::Foo() {
// code not locked
{ // scope of guard
std::lock_guard<std::mutex> lock( g_mutex );
// code to lock
} // end scope destroy guard unlock mutex
// other class code
}
Foo::someFunc() {
// Code to lock
std::lock_guard<std::mutex> lock( g_mutex );
}
I had discovered why it wasn't working properly for me. In my class's constructor it was calling a function from its parent or base class. The parent or base class was then calling a static member of this class and the static member function of this class was also using lock_guard on the same mutex.
After I found the problem; I had two options. I could of used 2 independent mutexes, one for the constructor specifically and one for the static method specifically. After some thought I figured well if I use 2, and I'm blocking the full constructor the current lock and mutex won't go out of scope until the class instance is destroyed; however the life of the class will be nearly the full life of the application. Then if I used a second mutex and lock guard within the static method, it would be redundant to wrap another lock_guard around an existing one. So I came to the conclusion that I needed to create a scoped block { } for the code that needed to be blocked by the mutex so that it can be unlocked after this section goes out of scope, then the constructor is free to call the static method and it can reuse the same mutex as it is now free. The class is now working properly and it is not crashing nor throwing exceptions when it shouldn't be.
I wonder if this code is fine or not:
#include <iostream>
#include <future>
struct Foo
{
Foo()
:m_a(0)
{
}
int m_a;
};
int main()
{
Foo f;
auto handle =
std::async( std::launch::async,
[](Foo* f) { std::cout << f->m_a << '\n'; } ,
&f
);
handle.get();
}
I believe m_a should be protected by a synchronization mechanism but my colleague says it is not necessary.
EDIT: To clarify my question: I am worried that the STORE operation from the constructor of Foo() happens after the LOAD operation from the other thread. I can't see what mechanism prevents the compiler from executing those instruction in this order.
EDIT: I believe an enthusiastic compiler could decide to inline the constructor, and delay the STORE operation for after the CALL operation to std::async. In which case the second thread could access m_a before it has been committed to memory.
Yes, this is correctly synchronised.
From the specification for async, C++11 30.6.8/5:
the invocation of async synchronizes with the invocation of f.
where f is the function argument to async (the lambda in your example).
Initialisation of f.m_a is sequenced before the call to async, and therefore before any access by the asynchronous function.
Furthermore,
the completion of the function f is sequenced before the shared state is made ready.
so the access must happen before the call to get() returns, and therefore before the object is destroyed.
I want to initialize a field in a constructor and never change it afterwards. I want the guarantee that after the constructor finished, every read of the field reads the initialized value, no matter in which thread the read happens.
Basically, I want the same guarantees as a final field gives in Java.
This is what I tried:
#include <atomic>
#include <iostream>
#include <thread>
struct Foo
{
Foo(int x) : x(x)
{
// ensure all writes are visible to other threads
std::atomic_thread_fence(std::memory_order_release);
}
int x;
};
void print_x(Foo const& foo)
{
// I don't think I need an aquire fence here, because the object is
// newly constructed, so there cannot be any stale reads.
std::cout << foo.x << std::endl;
}
int main()
{
Foo foo(1);
std::thread t(print_x, foo);
t.join();
}
Is this guaranteed to always print 1 or can thread t observe foo.x in an uninitialized state?
What if instead of using the member initializer x(x) an explicit assignment this->x = x; is used?
What if x is not an int but some class type?
Does making x a const int change anything with regards to thread safety?
Basically, if everything else is correct, there shouldn't be any
problem. After initializing the field, and before accessing it
in any thread, you need some sort of memory synchronization;
that's clear. Otherwise, how can the other threads know that it
is constructed. If you initialize it before starting the other
threads, then creating the threads will ensure the necessary
synchronization. (This only holds between the thread doing the
creation, and the created thread. Other already running threads
are not synchronization.) After that, as long as no thread
modifies the value, no synchronization is needed.
With regards to your code, you don't need the fence, because the
value is initialized before any of the other threads are
created, and creating the thread ensures the necessary
synchronization.