互斥锁的使用(学习笔记)
在我们上一章节学习了多线程,我们可以得知在一个进程里,主控线程,与多个子线程共享资源(比如全局变量),但是,我们发现有弊端,它们都可以修改共享资源里面的数据,并且运行 无先后顺序。
因此、同步和互斥就是用于解决这两个问题的。
一、什么是同步、什么是互斥?
互斥:
一个公共资源同一时刻只能被一个进程或线程使用,多个进程或线程不能同时使用公共资源。具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:
两个或两个以上的进程或线程在运行过程中协同步调,按预定的先后次序运行。同步就是在互斥的基础上有顺序 。
POSIX标准中进程和线程同步和互斥的方法,主要有信号量和互斥锁两种方式。
二、互斥锁
2.1互斥锁的概念
mutex是一种简单的加锁的方法来控制对共享资源的访问,mutex只有两种状态,
即上锁(lock)和解锁(unlock)。
在访问该资源前,首先应申请mutex,
如果mutex处于unlock状态,则会申请到mutex并立即lock;
如果mutex处于lock状态,则默认阻塞申请者。
unlock(解锁)操作应该由lock者进行。
2.2互斥锁的操作
第一步:初始化互斥锁
mutex用 pthread_mutex_t 数据类型表示,在使用互斥锁前,必须先对它进行初始化
初始化互斥锁有两个种方法:
一种静态分配互斥锁
一种动态分配互斥锁(常用)
1) 静态分配的互斥锁:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
2)动态分配互斥锁(常用):
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
在所有使用过此互斥锁的线程都不再需要使用时候,应调用pthread_mutex_destroy销毁
互斥锁。
三、互斥锁各函数
3.1初始化互斥锁
头文件
#include <pthread.h>
函数int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
功能:初始化一个互斥锁
参数:mutex:指定的互斥锁
mutexattr:互斥锁的属性,为NULL表示默认属性
返回值:
成功:0
3.2、互斥锁上锁(阻塞等待)常用
头文件:
#include <pthread.h>
函数:int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:对互斥锁上锁,若已经上锁,则调用者一直阻塞到互斥锁解锁
参数:
mutex:指定的互斥锁
返回值:成功:0
失败:非0
3.3 互斥锁上锁(非阻塞等待)只需了解
头文件:
#include <pthread.h>
函数:int pthread_mutex_trylock(pthread_mutex_t *mutex);
功能:对互斥锁上锁,若已经上锁,则上锁失败,函数立即返回。
参数:
mutex:互斥锁地址。
返回值:
成功:0
失败:非0
3.4、互斥锁解锁
头文件
#include <pthread.h>
函数:int pthread_mutex_unlock(pthread_mutex_t * mutex);
功能:对指定的互斥锁解锁。
参数:
mutex:互斥锁地址。
返回值:
成功:0
失败:非0
3.5、销毁互斥锁
头文件
#include <pthread.h>
函数:int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:销毁指定的一个互斥锁。
参数:
mutex:互斥锁地址。
返回值:成功:0
失败:非0。
四、案例:有两张银行卡,一张是主卡,另外一张副卡,都去取钱。
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include <unistd.h>int money=10000; //卡一共有10000元pthread_mutex_t mymutex;void *pthread_fun1(void *arg)
{int getmoney; //实际取的钱int yu_er; //卡余额int withdraw=4800; //预先想取的钱数pthread_mutex_lock(&mymutex);printf("张三使用主卡去取钱 \n");sleep(1);printf("张三正在取钱 \n");if(money < withdraw){getmoney=0;yu_er =money;}else if(money >= withdraw){getmoney=withdraw;yu_er=money-withdraw;} money = yu_er;sleep(1);printf("张三预先想取%d元 实际取了%d元 卡里余额%d元\n",withdraw,getmoney,yu_er);pthread_mutex_unlock(&mymutex);
}void *pthread_fun2(void *arg)
{int getmoney; //实际取的钱int yu_er; //卡余额int withdraw1=2800; //预先想取的钱数pthread_mutex_lock(&mymutex);printf("李四使用副卡去取钱 \n");sleep(1);printf("李四正在取钱 \n");if(money < withdraw1){getmoney=0;yu_er =money;}else if(money >= withdraw1){getmoney=withdraw1;yu_er=money-withdraw1;} money = yu_er;
sleep(1);
printf("李四预先想取 %d元 实际取了%d元 卡里余额%d元\n",withdraw1,getmoney,yu_er);pthread_mutex_unlock(&mymutex);
}
int main()
{ int ret1;int ret2;pthread_t pthread1;pthread_t pthread2;pthread_mutex_init(&mymutex,NULL);if((ret1=pthread_create(&pthread1,NULL,pthread_fun1,NULL))!=0){ perror("fail to pthread_create1");exit(1); }if((ret2=pthread_create(&pthread2,NULL,pthread_fun2,NULL))!=0){ perror("fail to pthread_create2");exit(1); } if(pthread_join(pthread1,NULL)!=0){perror("fail to pthread_join1");exit(1);} if(pthread_join(pthread2,NULL)!=0){perror("fail to pthread_join2");exit(1);}pthread_mutex_destroy(&mymutex);return 0;}
运行结果
张三使用主卡去取钱
张三正在取钱
张三预先想取4800元 实际取了4800元 卡里余额5200元
李四使用副卡去取钱
李四正在取钱
李四预先想取 2800元 实际取了2800元 卡里余额2400元
互斥锁的使用(学习笔记)相关推荐
- MIT的学习资料(reading部分)锁与同步学习笔记
MIT的学习资料(reading部分)锁与同步学习笔记 系统构件题材及问题探讨 锁和同步 目标 了解一个锁是用于保护共有的可变数据 能够认识到的僵局以及知道战略,以防止它 知道监视器模式,并能够将其应 ...
- mysql悲观锁 更新_MySQL学习笔记(四)悲观锁 for update
恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...
- java同步锁优化方案学习笔记(偏向锁,轻量级锁,自旋锁,重量级锁)
目录 一,概述 二,CAS算法 三,Java对象的对象头,以及Mark Word 四,偏向锁 Baised Lock 五,轻量级锁 六,自旋锁 SpinLock 七,重量级锁 八,在应用层提高锁效率的 ...
- JUC.Condition学习笔记[附详细源码解析]
JUC.Condition学习笔记[附详细源码解析] 目录 Condition的概念 大体实现流程 I.初始化状态 II.await()操作 III.signal()操作 3个主要方法 Conditi ...
- 学习笔记(19):Python网络编程并发编程-互斥锁
立即学习:https://edu.csdn.net/course/play/24458/296430?utm_source=blogtoedu 1.互斥锁: 多进程间的内存是相互隔离的,因此其数据也是 ...
- 学习笔记(26):Python网络编程并发编程-GIL与自定义互斥锁的区别
立即学习:https://edu.csdn.net/course/play/24458/296443?utm_source=blogtoedu 1.GIL的基本概念 答:GIL本质上就是一把锁,只是他 ...
- 学习笔记(20):Python网络编程并发编程-互斥锁与join的区别
立即学习:https://edu.csdn.net/course/play/24458/296432?utm_source=blogtoedu 互斥锁与join的异同: 1.同:都是将多进程并发模式变 ...
- Go 学习笔记(23)— 并发(02)[竞争,锁资源,原子函数sync/atomic、互斥锁sync.Mutex]
本文参考 <Go 语言实战> 1. 竞争状态简述 如果两个或者多个 goroutine 在没有互相同步的情况下,访问某个共享的资源,并试图同时读和写这个资源,就处于相互竞争的状态,这种情况 ...
- 进程通信学习笔记(互斥锁和条件变量)
1.互斥锁:上锁和解锁 Posix互斥锁作为数据类型pthread_mutex_t的变量声明.如果互斥锁变量是静态分配的,那么可以把它初始化成常值PTHREAD_MUTEX_INITIALIZER.如 ...
最新文章
- Python高级特性(切片,迭代,列表生成式,生成器,迭代器)
- Windows ninja
- 前端一HTML:十三:css的三大特性
- Asp.net Core 使用Redis存储Session
- Go报错:more than one character in rune literal
- 第七章数组答案C语言,c语言复习题及答案第七章数组.docx
- 高德联手饿了么:外卖小哥跑出偏远地区活地图
- php switch正则表达式,switch的用法以及正则表达式简单的用法
- 怎么把文件上传云服务器上,如何把文件上传到云服务器上
- JS void运算符
- Grid使用 ComboBox Binding DateTime Format WPF
- 长假终结踏上归途 网络电话延续团圆亲情
- 并发与计算机体系结构
- Python更改pip镜像源
- 配置eclipse插件
- 广州地铁公厕(洗手间)和母婴室信息汇总
- 计算机中三大总线:地址总线、数据总线、控制总线
- Navicat 11 Premium中文破解版使用心得
- if while的用法
- 中国石油大学(北京)-《 修井工程》第二阶段在线作业