2
\$\begingroup\$

I messed a little bit with pthreads and needed an alternative to the C++11 function std::lock (2 args are enough), and this is what I came up with:

void lock(pthread_mutex_t* m1, pthread_mutex_t* m2) {
  while(1) {
    pthread_mutex_lock(m1);

    if(pthread_mutex_trylock(m2) == 0) { // if lock succesfull
      break;
    }
    pthread_mutex_unlock(m1);
    sched_yield();
  }
}

It works fine so far. I am just not sure whether I missed some potential deadlock.

In addition, I am interested if I should do some more error checking. I am especially not that firm with C-style error checking.

\$\endgroup\$
  • \$\begingroup\$ Downvoter please explain! \$\endgroup\$ – inf Jul 17 '15 at 15:00
5
\$\begingroup\$

No this does not meet the definition of std::lock().

It (std::lock) guarantees that no matter what order you specify the locks in the parameter list you will not fall into a deadlock situation.

This basically means that the order you lock the mutex(s) in must be consistent (thus independent of the order they are in the parameter list). Your code is not (m1 is always locked first, m2 second; the actual order should be defined in terms of some immutable property of the underlying mutex (like its address)).

This also means that if a lock in the list is already locked it must be released so that the locks are acquired in the correct order.

Example of Deadlock:

 Time:     Thread-1          Thread-2

   0       lock(&g2)

   1                         lock(&g1)

   2       lock(&g1,&g2)

   3                         lock(&g2, &g1)

Thread 1 is now waiting for g1 (held by thread2), while thread 2 is waiting for g2 (held by thread 1).

\$\endgroup\$
  • \$\begingroup\$ Ok, thanks for the hints. Starting with your example, this is of course something I didn't think of as I didn't know that std::lock handles this, I supposed that it acts like a normal mutex::lock which gets double locked. While I can see that a proper ordering would fix the problem in the upper example, would the ordering still matter if we'd assume that the mutexs are both unlocked? I can't come up with a test which would deadlock in that case. \$\endgroup\$ – inf May 21 '12 at 21:40
  • \$\begingroup\$ To be more precise - assuming that a thread doesn't try to lock a mutex again which it already owns. \$\endgroup\$ – inf May 22 '12 at 4:30
  • \$\begingroup\$ @bamboon: If it already owns a lock. Then it must be release. If the locks are not acquired in the correct order you run the risk of deadlock. This is why std::lock imposes a strict ordering on lock acquisition. \$\endgroup\$ – Martin York Jun 14 '12 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.