一、互斥锁
1.1 基本API:
#include <pthread.h>
int
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int
pthread_mutex_destroy(pthread_mutex_t *mutex);
1.2 属性API:
int
pthread_mutexattr_init(pthread_mutexattr_t *attr);
int
pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int
pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling);
int
pthread_mutexattr_getprioceiling(pthread_mutexattr_t *attr, int *prioceiling);
int
pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);
int
pthread_mutexattr_getprotocol(pthread_mutexattr_t *attr, int *protocol);
int
pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
int
pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type);
int
pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *attr, int policy);
int
pthread_mutexattr_getpolicy_np(pthread_mutexattr_t *attr, int *policy);
1.3 本文范围:
本文重点描述
pthread_mutexattr_settype的用法,其他的可以参考:mutexattr中文描述
二、同一线程内重复申请锁
互斥锁,提供一种属性类型,允许同一线程内反复调用lock,但必须有对应的unlock操作,
2.1 伪代码:
1. 初始mutex和mutexattr实例
2. mutexattr设置反复调用的type
3.创建线程
4.主线程和子线程同时争抢资源,且子线程递归函数内,重复申请资源
2.2 C代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t g_mutex;
int test_recursive(int *n)
{
if(*n>10) return 0;
pthread_mutex_lock(&g_mutex);
printf("%s, n=%d\n", "slave",*n);
(*n)++;
test_recursive(n);
pthread_mutex_unlock(&g_mutex);
return 1;
}
void *func(void *context)
{
pthread_mutex_t *mut = context;
int n=0;
int m=0;
while(m++ < 5){
n = 0;
printf("#####slave loop %d\n", m);
test_recursive(&n);
usleep(10);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_mutexattr_t mutexatr;
int n=0;
if(pthread_mutexattr_init(&mutexatr)){
printf("mutexattr init failed, %s,%d\n",__FUNCTION__, __LINE__);
exit(0);
}
pthread_mutexattr_settype(&mutexatr, PTHREAD_MUTEX_RECURSIVE);
if(pthread_mutex_init(&g_mutex, &mutexatr)){
printf("mutex init err\n");
}
pthread_t pth;
pthread_create(&pth, NULL, func, &g_mutex);
int i=2;
while(i-- > 0){
pthread_mutex_lock(&g_mutex);
printf("master,%d\n", ++n);
pthread_mutex_unlock(&g_mutex);
usleep(10);
}
printf("waiting for subthread quit\n");
pthread_join(pth, NULL);
printf("subthread already quit\n");
pthread_mutexattr_destroy(&mutexatr);
pthread_mutex_destroy(&g_mutex);
return 0;
}
2.3 compile:
gcc -lpthread lock_mutex.c -o lock_mutex
2.4 run
./lock_mutex
2.5 result:
master,1
#####slave loop 1
slave, n=0
slave, n=1
slave, n=2
slave, n=3
slave, n=4
slave, n=5
slave, n=6
slave, n=7
slave, n=8
slave, n=9
slave, n=10
master,2
#####slave loop 2
slave, n=0
slave, n=1
slave, n=2
slave, n=3
slave, n=4
slave, n=5
slave, n=6
slave, n=7
slave, n=8
slave, n=9
slave, n=10
waiting for subthread quit
#####slave loop 3
slave, n=0
slave, n=1
slave, n=2
slave, n=3
slave, n=4
slave, n=5
slave, n=6
slave, n=7
slave, n=8
slave, n=9
slave, n=10
#####slave loop 4
slave, n=0
slave, n=1
slave, n=2
slave, n=3
slave, n=4
slave, n=5
slave, n=6
slave, n=7
slave, n=8
slave, n=9
slave, n=10
#####slave loop 5
slave, n=0
slave, n=1
slave, n=2
slave, n=3
slave, n=4
slave, n=5
slave, n=6
slave, n=7
slave, n=8
slave, n=9
slave, n=10
subthread already quit