Yaron Israeli Yaron Israeli - 1 month ago 13
C Question

pthread_mutex_lock how to not lock when it is the same thread

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.

Answer

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);
Comments