- 論壇徽章:
- 0
|
當多個線程共享使用同一段內存時,為了保證數據的一致性,就需要考慮到線程同步的
問題。
互斥量(mutex)
保證同一時間只有一個線程訪問數據,在線程訪問數據前先對數據加鎖,這樣數據只能
為該線程所用,其他試圖對數據加鎖的線程將被阻塞直到當前線程釋放對該數據的鎖。
#include
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr); 成功返回0,否則返回錯誤編號
pthread_mutex_t 是互斥量的數據類型。用它定義了一個互斥量之后還需要對互斥量作
初始化。初始化可直接賦值(如下),也可調用pthread_mutex_init來進行初始化。
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
一個互斥量只有兩個狀態(tài):unlocked(未上鎖,不屬于任一線程), locked(上鎖,屬于某
一線程)。一個互斥量不可能同時被兩個不同的線程鎖住。如果一個線程試圖對某一互斥
量上鎖,而該互斥量已為其他的線程鎖住,則該線程會被阻塞直到該互斥量被釋放。
pthread_mutex_init 用來初始化(mutex所指向的)互斥量,attr用來指定互斥量的屬性。
如果不指定屬性(attr為NULL),則使用默認的屬性。
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
成功返回0,否則返回錯誤編號
pthread_mutex_lock用于對互斥量上鎖。
如果該互斥量還未上鎖,則對其上鎖,且該互斥量就屬于調用線程,
函數pthread_mutex_lock立即返回。
如果該互斥量已經為別的線程鎖住,則pthread_mutex_lock阻塞調用線程,
直到該互斥量釋放。
如果該互斥量已經被調用線程鎖住,則調用線程再次用pthread_mutex_lock
該互斥量上鎖時,處理過程與互斥量的類型有關。
fast - 調用線程阻塞,直到該鎖釋放。這樣倒致調用線程死鎖。
error checking - pthread_mutex_lock立即返回,錯誤碼為EDEADLK。
recursive - pthread_mutex_lock 函數成功執(zhí)行,且記錄下調用線程對該互斥量上鎖的次數。
這樣的話,解鎖時pthread_mutex_unlock調用的次數也必須一致,這樣才能將鎖置為unlocked狀態(tài)。
pthread_mutex_trylock 與pthread_mutex_lock很相似,但是當互斥量已上鎖時,此函數
并不阻塞調用線程,此時它只會立即返回并附帶錯誤碼EBUSY。
pthread_mutex_unlock 釋放指定的互斥量。
如果互斥量的屬性是
fast - 將其置于unlocked狀態(tài)
recursive - 對一個互斥量有一個上鎖的計數器,此時使該計數器減1, 當計數器減到0時
則釋放該互斥量,變?yōu)閡nlocked狀態(tài)。
error checking -
int pthread_mutex_destroy(pthread_mutex_t *mutex);
成功返回0,否則返回錯誤編號
銷毀一個互斥量對象,釋放該互斥量的所持的一些資源。
//example:
#include stdio.h>
#include stdlib.h>
#include pthread.h>
struct foo {
int f_count;
pthread_mutex_t f_lock;
};
void
err_sys(const char *s)
{
printf("%s\n", s);
exit(-1);
}
struct foo *
foo_alloc(void)
{
struct foo *fp;
if ((fp = malloc(sizeof(struct foo))) != NULL) {
fp->f_count = 1;
if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
free(fp);
return NULL;
}
}
return fp;
}
void
foo_hold(struct foo *fp)
{
pthread_mutex_lock(&fp->f_lock);
fp->f_count++;
pthread_mutex_unlock(&fp->f_lock);
printf("foo_hold f_count = %d\n", fp->f_count);
}
void
foo_rele(struct foo *fp)
{
pthread_mutex_lock(&fp->f_lock);
if (--fp->f_count == 0) {
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_destroy(&fp->f_lock);
free(fp);
} else
pthread_mutex_unlock(&fp->f_lock);
printf(" foo_rele f_count = %d\n", fp->f_count);
}
void *
foo1(void *fp)
{
for (;;)
foo_hold((struct foo *)fp);
}
void *
foo2(void *fp)
{
for (;;)
foo_rele((struct foo *)fp);
}
int
main(void)
{
int err;
pthread_t tid1, tid2;
struct foo *tt;
tt = foo_alloc();
err = pthread_create(&tid1, NULL, foo1, (struct foo *)tt);
if (err != 0)
err_sys("pthread_create error");
err = pthread_create(&tid2, NULL, foo2, (struct foo *)tt);
if (err != 0)
err_sys("pthread_create error");
err = pthread_join(tid1, NULL);
if (err != 0)
err_sys("pthread_join error");
err = pthread_join(tid2, NULL);
if (err != 0)
err_sys("pthread_join error");
printf("\n---------- over -------------\n");
exit(0);
}
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u3/93566/showart_2180430.html |
|