I'm trying to do some stuff with pthreads and sync them:
How could I use mutex just for a group of threads ?
Let's say I have t0,t1, t2, .. t20. pthreads running at the same time, and I want to have a lock for the even numbers threads and other lock for the odd numbers threads... or one lock for the first ten, and other for the rest, or one lock for each one. I mean, grouping pthreads depending on its data (the fourth argument in this funcion:


and sharing the mutex for a group of pthreads.

I'm working on a kind of bank project and I want to lock all the phreads trying to access to a same account number. (as critical section CRUD operations)
Does it make sense ? or there is a better approach to do this ?
Thanks in advance for your help and time ;)



Mutual exclusion semaphores are not meant to be tied to specific threads, they're meant to protect specific resources.

In your case, that resource is the bank account. I'm not convinced that a mutex-per-account solution is a viable one, especially if your bank has tens of millions of customers, like some of the Chinese ones do :-)

A more workable approach may be to keep a list of the accounts currently being worked on in memory and use a single utex to protect that. The operations would then lock the mutex, check and possibly modify the list, then unlock the mutex.

The better approach that you're looking for is to use an ACID-type backing store (like a database) to ensure all updates are atomic.

  • +1 for suggesting an ACID-capable backing store. The list of accounts and a single mutex is not without additional work. You'd need to learn condition variables to avoid busy-waiting for your account to become unlocked. – Adam Hawes Nov 14 '11 at 4:16
  • Hi @paxdiablo, thanks for your answer. You mean have one list for all accounts ? so the mutex will protect this list, and any operation will have to check that list before proceed.. but what if I want threads working on different accounts at the same time, this is one list for account ? – jcosta Nov 14 '11 at 18:42
  • @jcosta, you don't lock the mutex while you're working on the account, you lock it while you're working on the list. Example: one thread wants to work on account #7. It locks list then checks to ensure no-one else is working on it. If someone else is, it unlocks mutex and errors. If not, it claims ownership of that account (stores its thread ID against it), unlocks mutex and begins work. Once finished, it locks, removes ownership and unlocks. The mutex is only held during the updates to the list itself so different threads can work on different accounts. – paxdiablo Nov 14 '11 at 22:26
  • @paxdiablo: Rather than "If someone else is [using the account], it unlocks mutex and errors" you probably want "Until the account is available, wait on a condition variable" (with the condition variable being signalled whenever a thread gives up ownership of an account). – caf Nov 14 '11 at 22:40
  • thank you both. I'll try with these approaches. @caf when you say wait, do you mean a pthread_cond_wait() ? the same threads that will lock and unlock the mutex will control the condition too, isn't? or the condition is for other thread ? Thanks again. – jcosta Nov 15 '11 at 2:32

It's up to you which threads share a given mutex. If you want a mutex only shared by the even-numbered threads, then all you have to do is ensure that that mutex is only accessed by the even-numbered threads.

Having said that, the right way to use a mutex is normally to associate it with a given set of data not a particular set of code. In your account number case, you could create one mutex for each account object, and ensure that any thread that accesses an account first locks the corresponding mutex (and unlocks it when it is done).

  • thanks @caf, understood, but how implement one mutex per bank account ? I mean, a mutex is a variable: pthread_mutex_t shared between threads.. so you mean add one variable per account? (again, sorry if it's a noob question) – jcosta Nov 14 '11 at 19:26
  • @jcosta: Yes - for example, if you already have a struct that represents a single bank account, you could add a pthread_mutex_t to that struct. You would need to initialise it with pthread_mutex_init() when the struct is first created (and before it is made visible to other threads), and tear it down with pthread_mutex_destroy() when the struct is being deallocated. – caf Nov 14 '11 at 22:30

In general you don't lock threads - you lock data structures, where any/all threads that want to access that data structure has to acquire the data structure's mutex.

For your case, this means one mutex per bank account.

The next problem is that some things need to access multiple data structures. An example of this would be transferring $100 from one account to another (where you want to lock both accounts, then reduce the balance of the first account and increase the balance of the second account, then release both locks). This can lead to deadlocks. For example, if one thread wants to lock A then B, and another thread wants to lock B then A; then the first thread might lock A and the second thread might lock B, and then neither thread will be able to get the second lock that they need.

The solution to that problem is to have a global "lock order" and only acquire locks in that order.

For your case you have account numbers. If a thread wants to lock 2 or more accounts, then it determines which accounts, then sorts the list of accounts (e.g. from lowest account number to highest account number), then acquires all the locks it needs in that order. Once the thread has acquired all the locks it needs, it does whatever it has to do, then releases all the locks it acquired in the reverse order.

  • Hi @Brendan, thanks, yes you're right about using lock order to prevent deadlocks.. I'll do it that way. But how implement one mutex per bank account ? I mean, a mutex is a variable: pthread_mutex_t shared between threads.. so you mean add one variable per account? (sorry if it's a noob question) – jcosta Nov 14 '11 at 18:33

Your Answer

