程式扎記: [C++ 常見問題] 線程的同步 (synchronized) : Mutex

標籤

2010年10月10日 星期日

[C++ 常見問題] 線程的同步 (synchronized) : Mutex

前言 : 
The threads library provides three synchronization mechanisms: 

• mutexes - Mutual exclusion lock: Block access to variables by other threads. This enforces exclusive access by a thread to a variable or set of variables.
• joins - Make a thread wait till others are complete (terminated).
• condition variables - data type pthread_cond_t

這裡將會對 mutexes 作簡單使用介紹 : 

Mutexes 介紹 : 
Mutexes are used to prevent data inconsistencies due to race conditions. A race condition often occurs when two or more threads need to perform operations on the same memory area, but the results of computations depends on the order in which these operations are performed. Mutexes are used for serializing shared resources. Anytime a global resource is accessed by more than one thread the resource should have a Mutex associated with it. One can apply a mutex to protect a segment of memory ("critical region") from other threads. Mutexes can be applied only to threads in a single process and do not work between processes as do semaphores. 
Example threaded function : 
* Without Mutex : 
  1. int counter=0;  
  2.   
  3. /* Function C */  
  4. void functionC() {  
  5.    counter++  
  6. }  
* With Mutex : 
  1. /* Note scope of variable and mutex are the same */  
  2. pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;  
  3. int counter=0;  
  4.   
  5. /* Function C */  
  6. void functionC(){  
  7.    pthread_mutex_lock( &mutex1 );  
  8.    counter++  
  9.    pthread_mutex_unlock( &mutex1 );  
  10. }  

If register load and store operations for the incrementing of variable counter occurs with unfortunate timing, it is theoretically possible to have each thread increment and overwrite the same variable with the same value. Another possibility is that thread two would first increment counter locking out thread one until complete and then thread one would increment it to 2. 

範例代碼 : 
* thread_sample.h 代碼 : 
  1. #include   
  2. #include   
  3. #include   
  4.   
  5. /** 
  6. * Thread Synchronization : Mutex 
  7. */  
  8. void threadSampleTest2(bool b);  
* thread_sample.cpp 代碼 : 
  1. #include "thread_sample.h"  
  2.   
  3. pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;  
  4. int counter = 0;  
  5.   
  6. void* functionC(void*);  
  7. void threadSampleTest2(bool b) {  
  8.     if(b) {  
  9.         int rc1, rc2;  
  10.         pthread_t thread1, thread2;  
  11.         void* (*pmf)(void*);  
  12.         pmf = functionC;  
  13.         /* Create independent threads each of which will execute functionC */  
  14.         if((rc1 = pthread_create(&thread1, NULL,&functionC, NULL))) {  
  15.             printf("Thread1 create fail(%d)!\n", rc1);  
  16.         }  
  17.         if((rc2 = pthread_create(&thread2, NULL,&functionC, NULL))) {  
  18.             printf("Thread2 create fail(%d)!\n", rc2);  
  19.         }  
  20.         /* Wait till threads are complete before main continues. Unless we  */  
  21.         /* wait we run the risk of executing an exit which will terminate   */  
  22.         /* the process and all threads before the threads have completed.   */  
  23.         pthread_join( thread1, NULL);  
  24.         pthread_join( thread2, NULL);  
  25.         //exit(0);  
  26.     }  
  27. }  
  28.   
  29. void *functionC(void*){  
  30.    pthread_mutex_lock( &mutex1 );  
  31.    counter++;  
  32.    printf("Counter value: %d\n",counter);  
  33.    pthread_mutex_unlock( &mutex1 );  
  34.    return NULL;  
  35. }  

執行結果 : 
When a mutex lock is attempted against a mutex which is held by another thread, the thread is blocked until the mutex is unlocked. When a thread terminates, the mutex does not unless explicitly unlocked. Nothing happens by default. 
Counter value: 1
Counter value: 2


補充說明 : 
* Linux Tutorial : POSIX thread coding 

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!