一个进程中的多个线程是共享同一段资源的,由于线程对资源的竞争引出了锁。其中mutex是一种简单的加锁方法,这个互斥锁只有两种状态,那就是上锁和解锁,可以把互斥锁看作是某种意义上的全局变量。在某一时刻,只能有一个线程取得这个互斥上的锁,拥有上锁状态的线程可以对共享资源进行操作,而其他线程在该线程未解锁之前,够会被挂起,直到上锁的线程解开锁。可以这么说,互斥锁使得共享资源按序的在各个线程上操作。
互斥锁的操作主要包括互斥锁初始化、上锁、判断上锁、解锁、摧毁互斥锁。其中互斥锁可以分为快速互斥锁、递归互斥锁这检错互斥锁。这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要等待挂起。快速锁是指调用线程会阻塞直到线程锁得到解锁为止。递归锁能够成功地返回并且增加调用线程在互斥上的加锁次数,比如一个链表在进行插入的操作时,可以进行查找的操作。检错锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误的信息。
pthread_mutex_init
函数原型: int pthread_mutex_init (pthread_mutex_t* mutex,
const pthread_mutexattr_t* mutexattr);
上锁函数:
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_trylock (pthread_mutex_t* mutex);
int pthread_mutex_unlock (pthread_mutex_t* mutex);
int pthread_mutex_destroy (pthread_mutex_t* mutex);
程序示例如下:
#include
#include
#include
#include
#define return_if_fail(p) \
if(!p) { printf("[%s]:func error!", __func__); return; }
typedef struct _PrivInfo {
pthread_mutex_t mutex;
int lock_var;
time_t end_time;
}PrivInfo;
void info_init(PrivInfo *thiz);
void *pthread_function1(void *paramthiz);
void *pthread_function2(void *paramthiz);
int main (int argc, char** argv) {
pthread_t pt_1 = 0;
pthread_t pt_2 = 0;
int ret = 0;
PrivInfo *thiz = NULL;
thiz = (PrivInfo*)malloc(sizeof(PrivInfo));
if(NULL == thiz) {
return -1;
}
info_init(thiz);
ret = pthread_create(&pt_1, NULL, pthread_function1, (void*)thiz);
if(0 != ret) {
perror("pthread1 creation failed!");
}
ret = pthread_create(&pt_2, NULL, pthread_function2, (void*)thiz);
if(0 != ret) {
perror("pthread2 creation failed!");
}
pthread_join(pt_1, NULL);
pthread_join(pt_2, NULL);
pthread_mutex_destroy(&thiz->mutex);
free(thiz);
thiz = NULL;
return 0;
}
void info_init(PrivInfo *thiz) {
return_if_fail(&thiz != NULL);
thiz->lock_var = 0;
thiz->end_time = time(NULL) + 10;
pthread_mutex_init(&thiz->mutex, NULL);
return;
}
void *pthread_function1(void *paramthiz) {
int ret = 0;
int i = 0;
PrivInfo *thiz = (PrivInfo *)paramthiz;
while(time(NULL) < thiz->end_time) {
ret = pthread_mutex_lock(&thiz->mutex);
if(0 != ret) {
perror("pthread1_mutex_lock error.\n");
} else {
printf("pthread1 lock the variable: %d\n", thiz->lock_var);
}
for(; i<2; i++) {
sleep(1);
thiz->lock_var ++;
}
ret = pthread_mutex_unlock (&thiz->mutex);
if (ret != 0) {
perror ("pthread1_mutex_unlock error.\n");
} else {
printf ("pthread1: pthread1 unlock the variable: %d\n", thiz- >lock_var);
break;
}
}
pthread_exit(NULL);
}
void *pthread_function2(void *paramthiz) {
int ret = 0;
PrivInfo *thiz = (PrivInfo *)paramthiz;
while(time(NULL) < thiz->end_time) {
ret = pthread_mutex_trylock(&thiz->mutex);
if(EBUSY == ret) {
printf("pthread2:the variable has been lacked by
thread1:\n");
} else {
if(0 != ret) {
perror ("pthread2_mutex_lock error.\n");
} else {
printf("pthread2 lock the variable: %d\n",
thiz->lock_var);
}
}
ret = pthread_mutex_unlock (&thiz->mutex);
if (ret != 0) {
perror ("pthread2_mutex_unlock error.\n");
} else {
printf ("pthread2: pthread2 unlock the variable: %d\n",
thiz->lock_var);
}
sleep(2);
}
pthread_exit(NULL);
}