红联Linux门户
Linux帮助

linux多线程之互斥锁

发布时间:2016-08-17 15:14:45来源:linux网站作者:带鱼兄
基本概念:
互斥变量是用pthread_mutex_t数据类型表示的。在使用互斥变量以前,必须首先对它进行初始化,可以把它设置为常量PTHREAD_MUTEX_INITIALIZER(只适用于静态分配的互斥量),也可以通过调用pthread_mutex_init函数进行初始化。如果动态分配互斥量(例如,通过调用malloc函数),在释放内存前需要调用pthread_mutex_destroy。
 
一、锁的初始化与销毁
PTHREAD_MUTEX_DESTROY(P)   POSIX Programmer's Manual  PTHREAD_MUTEX_DESTROY(P)   
NAME  
pthread_mutex_destroy,  pthread_mutex_init  -  destroy and initialize a  
mutex  
SYNOPSIS  
#include <pthread.h>  
int pthread_mutex_destroy(pthread_mutex_t *mutex);  
int pthread_mutex_init(pthread_mutex_t *restrict mutex,  
const pthread_mutexattr_t *restrict attr);  
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  
两个函数的返回值:若成功,返回0;否则,返回错误码
 
二、加锁解锁
PTHREAD_MUTEX_LOCK(P)POSIX Programmer's ManualPTHREAD_MUTEX_LOCK(P)   
NAME  
pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock - lock and unlock a mutex
SYNOPSIS  
#include <pthread.h>  
int pthread_mutex_lock(pthread_mutex_t *mutex);  
int pthread_mutex_trylock(pthread_mutex_t *mutex);  
int pthread_mutex_unlock(pthread_mutex_t *mutex);  
所有函数的返回值:若成功,返回0;否则返回错误码
如果线程不希望被阻塞,它可以使用pthread_mutex_trylock尝试对互斥量进行加锁。如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,不会出现阻塞直接返回0,否则pthread_mutex_trylock就会失败,不能锁住互斥量,返回EBUSY.
 
三、支持超时的阻塞lock
PTHREAD_MUTEX_TIMEDLOCK(P)   POSIX Programmer's Manual   PTHREAD_MUTEX_TIMEDLOCK(P) 
NAME  
pthread_mutex_timedlock - lock a mutex (ADVANCED REALTIME)  
SYNOPSIS  
#include <pthread.h>  
#include <time.h>  
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,  
const struct timespec *restrict abs_timeout);  
返回值:若成功,返回0;否则,返回错误码编号
当线程试图获取一个已加锁的互斥量时,pthread_mutex_timedlock函数在达到超时时间值时,不会对互斥量进行加锁,而是返回错误码ETIMEDOUT
 
四、互斥量属性
PTHREAD_MUTEXATTR_DESTROY(P) POSIX Programmer's Manual PTHREAD_MUTEXATTR_DESTROY(P)   
NAME  
pthread_mutexattr_destroy, pthread_mutexattr_init - destroy and initialize the mutex attributes object  
SYNOPSIS  
#include <pthread.h>  
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);  
int pthread_mutexattr_init(pthread_mutexattr_t *attr);  
两个函数的返回值:若成功,返回0;否则,返回错误码编号
互斥量属性是用pthread_mutexattr_t结构表示的。对于非默认属性,可以用pthread_mutexattr_init初始化pthread_mutexattr_t结构,用pthread_mutexattr_destroy来反初始化。pthread_mutexattr_init函数将用默认的互斥量属性初始化pthread_mutexattr_t结构。
值得注意的3个属性是:
1.进程共享属性:如果进程共享互斥量属性设置为PTHREAD_PROCESS_SHARED,从多个进程彼此之间共享的内存数据块中分配的互斥量就可以用于这些进程的同步。
2.健壮属性:互斥量健壮属性与在多个进程共享的互斥量有关
3.类型属性:类型互斥量属性控制着互斥量的锁定特性,可以用pthread_mutexattr_gettype函数得到互斥量类型属性,用pthread_mutexattr_settype函数修改互斥量类型属性。
 
例子1,静态分配互斥量:gcc pthread_mutex.c -pthread
#include <pthread.h>  
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <errno.h>  
static int num = 0;  
static int count = 100000;  
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  
void Perror(const char *s)  
{  
perror(s);  
exit(EXIT_FAILURE);  
}  
void* fun2(void *arg)  
{  
pthread_t thread_id = pthread_self();  
printf("the thread2 id is %ld\n", (long)thread_id);  
// ++  
int i = 1;  
for (; i<=count; ++i) {  
pthread_mutex_lock(&mutex);  
num += 1;  
pthread_mutex_unlock(&mutex);  
}  
}  
int main()  
{  
int err;  
pthread_t thread1;  
pthread_t thread2;  
thread1 = pthread_self();  
printf("the thread1 id is %ld\n", (long)thread1);  
// create thread  
err = pthread_create(&thread2, NULL, fun2, NULL);  
if (err != 0) {  
Perror("can't create thread2\n");  
}  
// detach thread3  
err = pthread_detach(thread2);  
if (err != 0) {  
Perror("can't detach thread2\n");  
}  
// ++  
int i = 1;  
for (; i<=count; ++i) {  
pthread_mutex_lock(&mutex);  
num += 1;  
pthread_mutex_unlock(&mutex);  
}  
sleep(10);  
printf("The num is %d\n", num);  
return 0;  
}  
 
例子2,动态分配互斥量:gcc pthread_mutex.c -pthread
#include <pthread.h>  
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <errno.h>  
static int num = 0;  
static int count = 100000;  
static pthread_mutex_t* pmutex;   
void Perror(const char *s)  
{  
perror(s);  
exit(EXIT_FAILURE);  
}  
void* fun2(void *arg)  
{  
pthread_t thread_id = pthread_self();  
printf("the thread2 id is %ld\n", (long)thread_id);  
int i = 1;  
for (; i<=count; ++i) {  
pthread_mutex_lock(pmutex);  
num += 1;  
pthread_mutex_unlock(pmutex);  
}  
}  
int main()  
{  
int err;  
pthread_t thread1;  
pthread_t thread2;  
// init mutex  
pmutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));  
if (pthread_mutex_init(pmutex, NULL) != 0)  
Perror("pthread_mutex_init failed");  
thread1 = pthread_self();  
printf("the thread1 id is %ld\n", (long)thread1);  
// Create thread  
err = pthread_create(&thread2, NULL, fun2, NULL);  
if (err != 0) {  
Perror("can't create thread2\n");  
}
// detach thread3  
err = pthread_detach(thread2);  
if (err != 0) {  
Perror("can't detach thread2\n");  
}
int i = 1;  
for (; i<=count; ++i) {  
pthread_mutex_lock(pmutex);  
num += 1;  
pthread_mutex_unlock(pmutex);  
}
sleep(10);  
printf("The num is %d\n", num);
// destroy  
pthread_mutex_destroy(pmutex);  
free(pmutex); 
return 0;  
}  
 
ps:多进程间的互斥锁不在本文讨论范围。
 
本文永久更新地址://m.ajphoenix.com/linux/23395.html