Ads 468x60px

##EasyReadMore##

08 9月, 2016

[C] 互斥鎖 pthread_mutex_lock sample

說明:

1. 創建和銷毀 

有兩種方法創建互斥鎖,靜態方式和動態方式。POSIX定義了一個宏PTHREAD_MUTEX_INITIALIZER來靜態初始化互斥鎖,方法如下:
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
在LinuxThreads實現中,pthread_mutex_t是一個結構,而PTHREAD_MUTEX_INITIALIZER則是一個結構常量。

動態方式是採用pthread_mutex_init()函數來初始化互斥鎖,API定義如下:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
其中mutexattr用於指定互斥鎖屬性(見下),如果為NULL則使用缺省屬性。

pthread_mutex_destroy()用於註銷一個互斥鎖,API定義如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex)
銷毀一個互斥鎖即意味著釋放它所佔用的資源,且要求鎖當前處於開放狀態。由於在Linux中,互斥鎖並不佔用任何資源,因此LinuxThreads中的pthread_mutex_destroy()除了檢查鎖狀態以外(鎖定狀態則返回EBUSY)沒有其他動作。

2. 鎖操作 

鎖操作主要包括加鎖pthread_mutex_lock()、解鎖pthread_mutex_unlock()和測試加鎖pthread_mutex_trylock()三個,不論哪種類型的鎖,都不可能被兩個不同的線程同時得到,而必須等待解鎖。對於普通鎖和適應鎖類型,解鎖者可以是同進程內任何線程;而檢錯鎖則必須由加鎖者解鎖才有效,否則返回EPERM;對於嵌套鎖,文檔和實現要求必須由加鎖者解鎖,但實驗結果表明並沒有這種限制,這個不同目前還沒有得到解釋。在同一進程中的線程,如果加鎖後沒有解鎖,則任何其他線程都無法再獲得鎖。

int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)

pthread_mutex_trylock()語義與pthread_mutex_lock()類似,不同的是在鎖已經被佔據時返回EBUSY而不是掛起等待。


3.等待和激發 :

調用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,mutex保持鎖定狀態,並在線程掛起進入等待前解鎖。

激發條件有兩種形式,pthread_cond_signal()激活一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個;而pthread_cond_broadcast()則激活所有等待線程。

所以將 pthread_cond_signal 註解起來 ,程式會被整個 lock 住。

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 

pthread_mutex_t mutex; 
pthread_cond_t cond; 

void * child1(void *arg) 
{ 
// pthread_cleanup_push(pthread_mutex_unlock,&mutex); /* comment 1 */ 
 while(1){ 
  printf("thread 1 get running \n"); 
  printf("thread 1 pthread_mutex_lock returns %d\n", 
  pthread_mutex_lock(&mutex)); 
  pthread_cond_wait(&cond,&mutex); 
  printf("thread 1 condition applied\n"); 
  pthread_mutex_unlock(&mutex); 
  sleep(5); 
 } 
// pthread_cleanup_pop(0); /* comment 2 */ 
} 

void *child2(void *arg) 
{ 
 while(1){ 
  sleep(3); /* comment 3 */ 
  printf("thread 2 get running.\n"); 
  printf("thread 2 pthread_mutex_lock returns %d\n", 
  pthread_mutex_lock(&mutex)); 
  pthread_cond_wait(&cond,&mutex); 
  printf("thread 2 condition applied\n"); 
  pthread_mutex_unlock(&mutex); 
  sleep(1); 
 } 
} 

int main(void) 
{ 
 pthread_t tid1,tid2; 
 
 printf("hello, condition variable test\n"); 
 pthread_mutex_init(&mutex,NULL); 
 pthread_cond_init(&cond,NULL); 
 pthread_create(&tid1,NULL,child1,NULL); 
 pthread_create(&tid2,NULL,child2,NULL); 
 
 do{ 
  sleep(2); /* comment 4 */ 
//  pthread_cancel(tid1); /* comment 5 */ 
  sleep(2); /* comment 6 */ 
  pthread_cond_signal(&cond); 
 }while(1); 
 
 sleep(100); 
 pthread_exit(0);

}



output:

hello, condition variable test
thread 1 get running
thread 1 pthread_mutex_lock returns 0
thread 2 get running.
thread 2 pthread_mutex_lock returns 0
thread 1 condition applied
.........

參考:

轉貼: pthread 解讀(三) @ 血落閣 :: 隨意窩 Xuite日誌 - http://goo.gl/ygLp4x

0 意見:

張貼留言

 
Blogger Templates