linux多线程-互斥锁

来源:互联网 发布:淘宝删除差评步骤 编辑:程序博客网 时间:2024/06/02 02:20

互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源。

实现机制:(函数说明)

需要的头文件:pthread.h

1) 初始化互斥锁

函数的原型:int  pthread_mutex_init(pthread_mutex_t*mp, const pthread_mutexattr_t *mattr)

函数的参数:mutex:互斥锁

            mattr:PTHREAD_MUTEX_INITIALIZER创建快速互斥锁

                  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP创建递归互斥锁

                  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP创建检错互斥锁

2)锁定互斥锁

函数的原型:int pthread_mutex_lock(pthread_mutex_t *mutex);

返回值:成功0,出错-1

函数的说明:

当 pthread_mutex_lock() 返回时,该互斥锁已被锁定。调用线程是该互斥锁的属主。如果该互斥锁已被另一个线程锁定和拥有,则调用线程将阻塞,直到该互斥锁变为可用为止。

如果互斥锁类型为 PTHREAD_MUTEX_NORMAL,则不提供死锁检测。尝试重新锁定互斥锁会导致死锁。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或未锁定,则将产生不确定的行为。

如果互斥锁类型为 PTHREAD_MUTEX_ERRORCHECK,则会提供错误检查。如果某个线程尝试重新锁定的互斥锁已经由该线程锁定,则将返回错误。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。

如果互斥锁类型为 PTHREAD_MUTEX_RECURSIVE,则该互斥锁会保留锁定计数这一概念。线程首次成功获取互斥锁时,锁定计数会设置为 1。线程每重新锁定该互斥锁一次,锁定计数就增加 1。线程每解除锁定该互斥锁一次,锁定计数就减小 1。 锁定计数达到 0 时,该互斥锁即可供其他线程获取。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。

如果互斥锁类型是 PTHREAD_MUTEX_DEFAULT,则尝试以递归方式锁定该互斥锁将产生不确定的行为。对于不是由调用线程锁定的互斥锁,如果尝试解除对它的锁定,则会产生不确定的行为。如果尝试解除锁定尚未锁定的互斥锁,则会产生不确定的行为。

 

3)解除锁定互斥锁

函数的原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);

返回值:pthread_mutex_unlock()在成功完成之后会返回零。

其他任何返回值都表示出现了错误。如果出现以下情况,该函数将失败并返回对应的值。

EPERM:当前线程不拥有互斥锁。

函数的说明:pthread_mutex_unlock()可释放 mutex 引用的互斥锁对象。互斥锁的释放方式取决于互斥锁的类型属性。如果调用pthread_mutex_unlock() 时有多个线程被 mutex 对象阻塞,则互斥锁变为可用时调度策略可确定获取该互斥锁的线程。对于 PTHREAD_MUTEX_RECURSIVE 类型的互斥锁,当计数达到零并且调用线程不再对该互斥锁进行任何锁定时,该互斥锁将变为可用。

4)使用非阻塞互斥锁锁定

函数的原型:int pthread_mutex_trylock(pthread_mutex_t *mutex);

返回值:pthread_mutex_trylock()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。

EBUSY:

由于 mutex 所指向的互斥锁已锁定,因此无法获取该互斥锁。

EAGAIN:描述:

由于已超出了 mutex 的递归锁定最大次数,因此无法获取该互斥锁。

函数的说明:pthread_mutex_trylock()是 pthread_mutex_lock() 的非阻塞版本。如果 mutex 所引用的互斥对象当前被任何线程(包括当前线程)锁定,则将立即返回该调用。否则,该互斥锁将处于锁定状态,调用线程是其属主。

5)销毁互斥锁

函数的原型:int pthread_mutex_destroy(pthread_mutex_t *mp);

返回值:

pthread_mutex_destroy()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。

EINVAL:mp 指定的值不会引用已初始化的互斥锁对象。

*/请注意,没有释放用来存储互斥锁的空间。

 

互斥锁实现机制:

#include <stdio.h>#include <pthread.h>pthread_mutex_t mutex;//两者有其一不加锁,两者同时打印,两者都加锁后先执行func1,后执行func2(执行顺序由系统决定)void *func1(void){    int i;    pthread_mutex_lock(&mutex);    for(i = 0; i < 5; i++)    {        printf("this is fun1.\n");sleep(1);    }    pthread_mutex_unlock(&mutex);}void *func2(void){    int i;    pthread_mutex_lock(&mutex);    for(i = 0; i < 5; i++)    {        printf("this is fun2.\n");sleep(1);    }    pthread_mutex_unlock(&mutex);}int main(){    pthread_t id1;    pthread_t id2;        pthread_mutex_init(&mutex, NULL);    pthread_create(&id1, NULL, (void *)func1, NULL);    pthread_create(&id2, NULL, (void *)func2, NULL);    pthread_join(id1, NULL);    pthread_join(id2, NULL);    pthread_mutex_destroy(&mutex);    return 0;}
运行结果:



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子喉咙有痰呼呼响怎么办 六个月宝宝鼻塞怎么办速效办法 两个月小孩鼻子不通气怎么办 一岁宝宝流清鼻涕怎么办 孩子鼻子里有鼻涕怎么办 宝宝晚上睡觉鼻子不通气怎么办 宝宝感冒睡觉鼻子不通气怎么办 宝宝3个月流鼻涕怎么办 小孩吃着了发烧怎么办 半岁宝宝鼻子塞怎么办 宝宝伤风鼻子不通气怎么办 二十天的宝宝伤风鼻子不通怎么办 一个多月的宝宝鼻子有鼻屎怎么办 2个月宝宝鼻子里有鼻屎怎么办 四个月婴儿感冒发烧怎么办 一个月婴儿感冒发烧怎么办 五个月婴儿感冒发烧怎么办 两个月的婴儿感冒发烧怎么办 9个月婴儿感冒发烧怎么办 两个月婴儿感冒鼻塞咳嗽怎么办 两个月婴儿感冒咳嗽流鼻涕怎么办 小孩感冒发烧怎么办速效办法 宝宝打喷嚏流清鼻涕怎么办 宝宝感冒流清鼻涕怎么办 2岁感冒流清鼻涕怎么办 小孩感冒流清鼻涕怎么办 4岁宝宝半夜发烧怎么办 四岁宝宝免疫力低下怎么办 两岁宝宝咳嗽流鼻涕怎么办 小婴儿流清鼻涕怎么办 14个月宝宝流鼻涕怎么办 小孩一直流黄鼻涕怎么办 咳嗽有痰 浓鼻涕怎么办 儿童鼻窦炎总反复流脓鼻涕怎么办? 宝宝感冒咳嗽流黄鼻涕怎么办 哺乳期感冒流清鼻涕怎么办 哺乳期打喷嚏流清鼻涕怎么办 哺乳期妈妈感冒流清鼻涕怎么办 哺乳期严重流清鼻涕怎么办 小孩每天都是脓鼻涕怎么办 夏天小孩咳嗽流黄脓鼻涕怎么办?