mutex锁的创建和销毁
mutex锁的属性
加锁、解锁、测试加锁
线程的同步
信号量是system V标准,线程库是prosix标准。每一个标准都觉得自己牛,就自己写一套。写进程用前面的信号量、写线程用锁。
linux锁的类型:
1.自旋锁:主要用在内核调度中。spinlock。自旋锁的效率更高。不睡觉,二是不停地看锁有没有打开。嵌入式开发采用。
2.互斥锁(睡眠锁):信号量、mutex。存在睡觉和唤醒的消耗。节省CPU资源,但是效率较低。
信号量:pv操作
mutex:加解锁
int pthread_mutex_init(pthread_mutex_t *
mutex, const pthread_mutexattr_t *mutexattr);
//mutexattr用于指定互斥锁属性,如果为NULL则
使用缺省属性。通常为NULL。
一、mutex锁的创建和销毁
静态初始化:不用。一般用动态初始化。
例:
int main(){
pthread_mutex_t
mutex1;
int ret;d
ret=
pthread_mutex_init(
&mutex1,NULL);
//创建锁
if(ret!=0){
printf("pthread_mutex_init failed ret=%d\n",ret);
return -1;
}
printf("mutex init success\n");
ret=
pthread_mutex_destroy(
&mutex1);
//销毁锁
if(ret!=0){
printf("pthread_mutex_destroy failed ret=%d\n",ret);
return -1;
}
return 0;
}
二、mutex锁的属性
互斥锁的属性结构体为:
typedef struct{
int __mutexkind;
//注意这里是两个下划线。在LinuxThreads实现中仅有一个锁类型属性__mutexkind.这个成员的值主要有三种。
}pthread_mutexattr_t;
PTHREAD_MUTEX_TIMED_NP
//缺省值。默认的情况下:单个线程加锁两次,第二次加锁会卡着
PTHREAD_MUTEX_RECURSIVE_NP
//嵌套锁。可以进行多次加锁。
PTHREAD_MUTEX_ERRORCHECK_NP
//检错锁。也没啥用。当加锁多次的时候,第二次加锁,会返回EDEADLK。
初始化方法:
方法一: //这种方法存在一个问题,就是__mutexkind这个变量,一旦变了之后,需要找他变成了什 么,再自己改。
pthread_mutex_t lock;
pthread_mutexattr_t
mutexattr;
mutexattr.__mutexkind = PTHREAD_MUTEX_RECURSIVE_NP;
pthread_mutex_init(&lock, &
mutexattr);
方法二:
//
用函数进行初始化,
比较暴力的初始化方法:memcpy.直接往结构体里面拷。
pthread_mutexattr_t
mutexattr;
int i ;
i=PTHREAD_MUTEX_ERRORCHECK_NP;
memcpy(
&mutexattr,
&i,sizeof(int));
方法三:
//这种方法比较常用。
pthread_mutexattr_t
mattr; //建立互斥锁的属性结构体
pthread_mutexattr_init(
&mattr); //对属性结构体进行初始化
pthread_mutexattr_settype(
&mattr,
PTHREAD_MUTEX_ERRORCHECK_NP); //改变属性
例子1:默认情况下,同一把锁加锁两次。会产生死锁。第二次加锁会卡着。
int main(){
pthread_mutex_t m1;
int ret;
ret=pthread_mutex_init(&m1,
NULL);
//默认情况
if(ret!=0){
printf("pthread_mutex_init failed,ret=%d\n",ret);
return -1;
}