课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
锁的应用在软件编程开发项目中是非常常见的一个编程技术,而今天我们就通过案例分析来了解一下,软件开发常用锁都有哪些类型。
1、互斥锁
即对互斥量进行分加锁,和自旋锁类似,不同的是竞争不到锁的线程会回去睡会觉,等到锁可用再来竞争,一个切入的线程加锁后,其他竞争失败者继续回去睡觉直到再次接到通知、竞争。互斥锁算是目前并发系统中常用的一种锁,POSIX、C++11、Java等均支持。处理POSIX的加锁比较普通外,C++和Java的加锁方式很有意思。C++中可以使用一种AutoLock(常见于chromium等开源项目中)工作方式类似auto_ptr智能指针,在C++11中官方将其标准化为std::lock_guard和std::unique_lock。Java中使用synchronized紧跟同步代码块(也可修饰方法)的方式同步代码,非常灵活。这两种实现都巧妙的利用各自语言特性实现了非常优雅的加锁方式。当然除此之外他们也支持传统的类似于POSIX的加锁模式。
2、读写锁
支持两种模式的锁,当采用写模式上锁时与互斥锁相同,是独占模式。但读模式上锁可以被多个读线程读取。即写时使用互斥锁,读时采用共享锁,故又叫共享-独占锁。一种常见的错误认为数据只有在写入时才需要锁,事实是即使是读操作也需要锁保护,如果不这么做的话,读写锁的读模式便毫无意义。
3、重入
也叫做锁递归,就是获取一个已经获取的锁。不支持线程获取它已经获取且尚未解锁的方式叫做不可递归或不支持重入。带重入特性的锁在重入时会判断是否同一个线程,如果是,则使持锁计数器+1(0代表没有被线程获取,又或者是锁被释放)。C++11中同时支持两种锁,递归锁std::recursive_mutex和非递归std::mutex。Java的两种互斥锁实现以及读写锁实现均支持重入。POSIX使用一种叫做重入函数的方法保证函数的线程安全,锁粒度是调用而非线程。
4、死锁
线程在执行过程中等待锁释放,如果存在多个线程相互等待已经被加锁的资源,就会造成死锁。大多数语言的锁实现都支持重入的一个重要原因是一个函数体内加锁的代码段中经常会调用其他函数,而其他函数内部同样加了相同的锁,在不支持重入的情况下,执行线程总是要获取自己尚未释放的锁。也就是说该条线程试图获取一个自己已经获取而尚未释放的锁。死锁就此产生。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。