2

I'm new to multi-threads programming and I got confused about where to declare mutex. I got the idea of mutex, lock/unlock by googling a lot. But I still don't know where I need to declare the pthread_mutex_t variable, and what's the difference.

For example here is Case 1:

#include <pthread.h> pthread_mutex_t count_mutex; long long count; void increment_count() { pthread_mutex_lock(&count_mutex); count = count + 1; pthread_mutex_unlock(&count_mutex); } 

Here is Case 2:

struct order_que { struct order **orders; int size; int head; int tail; pthread_mutex_t lock; }; void *ClientThread(void *arg) { struct client_arg *ca = (struct client_arg *)arg; int i; for(i=0; i < ca->order_count; i++) { ...... queued = 0; while(queued == 0) { pthread_mutex_lock(&(ca->order_que->lock)); ...... if(next == ca->order_que->tail) { pthread_mutex_unlock(&(ca->order_que->lock)); continue; } ...... pthread_mutex_unlock(&(ca->order_que->lock)); ...... } } return(NULL); } 

Could anyone tell me what's the difference between these two cases and why I need declare the mutex in this way?

7
  • The first case uses a single global mutex. Simple but not flexible. The second case allows different mutexes to be used for different threads as it is passed to the thread as part of its arg. For example, you may have two different queues that have seperate locking mutexes. Then the second method is more flexible as that same thread function can be used without changing any of its code - just need to invoke it with different arg values. Commented Dec 15, 2015 at 2:51
  • 1
    You declare it where it's needed, like any other instance of some var type. Commented Dec 15, 2015 at 2:51
  • 1
    In summary, they are both valid ways to set up the mutex. It's a matter of understanding their differences and knowing which is more appropriate to use to solve a particular problem. Commented Dec 15, 2015 at 2:53
  • Imagine pthread_mutex_t lock; was actually int i;, and pthread_mutex_lock was ++ and pthread_mutex_unlock was --, or something like that. Do you know the difference now? Commented Dec 15, 2015 at 2:56
  • By the way, in the second code block, there is no "the mutex". Commented Dec 15, 2015 at 2:56

1 Answer 1

1

Could anyone tell me what's the difference between these two cases and why I need declare the mutex in this way?

Generally speaking, mutex is designed to synchronize accesses (protect against race conditions) to a resource. Thus mutex declaration often follows the declaration of the resource it is intended to protect.

In case #1, the mutex syncs accesses to the global variable count - and thus it is declared globally, along with the variable. It guarantees that, when the increment_count() is called on different CPUs from different threads, the non-atomic arithmetics on the count variable would be performed in a consistent fashion, producing expected results.

In case #2, the mutex syncs accesses to the order_que ring buffer which (apparently) might be accessed from multiple threads. (Appears to be code for a job queue: the queue of items/jobs/etc, the threads should process in parallel.) The generic ring buffer requires arithmetics on the head and the tail pointers to enqueue and dequeue items. To guarantee the consistent results of the arithmetics on the head/tail (missing from your example) the mutex is used to synchronize the accesses to them. Thus the mutex is declared in the same context as the variables.

Sign up to request clarification or add additional context in comments.

1 Comment

@XiaoliChen, if it is the answer you were looking for, do not forget it to accept it as an answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.