建议性锁和强制性锁

1、锁的应用场景

假设有一个文件a,它有1000个字节,一个进程A打开a文件并使用lseek定位到文件到末尾的位置,准备写50个字节,同时进程B也打开这个a文件进行和进程A同样的操作,那么文件最后的内容并不是1000+50+50个字节,而是1050,两个进程后写入的内容将会覆盖前面写的内容,那么如何解决这种问题呢?

这种情况下,文件锁应运而生。

2、建议性锁

建议性锁flock,不具备强制性。一个进程使用flock将文件锁住,另一个进程可以直接操作正在被锁的文件,修改文件中的数据,原因在于flock只是用于检测文件是否被加锁,针对文件已经被加锁,另一个进程写入数据的情况,内核不会阻止这个进程的写入操作,也就是建议性锁的内核处理策略。

flock主要三种操作类型:
LOCK_SH,共享锁,多个进程可以使用同一把锁,常被用作读共享锁;
LOCK_EX,排他锁,同时只允许一个进程使用,常被用作写锁;
LOCK_UN,释放锁;

进程使用flock尝试锁文件时,如果文件已经被其他进程锁住,进程会被阻塞直到锁被释放掉,或者在调用flock的时候,采用LOCK_NB参数,在尝试锁住该文件的时候,发现已经被其他服务锁住,会返回错误,errno错误码为EWOULDBLOCK。即提供两种工作模式:阻塞与非阻塞类型。

多个锁同时存在的状态如下:

|       LOCK_SH        |      LOCK_EX

-----------------------------------------------------------------------

LOCK_EX         |            NO               |          NO

LOCK_SH         |            YES             |          NO

3、建议性锁的继承与释放

flock()根据调用时operation参数传入LOCK_UN的值来释放一个文件锁。

此外,锁会在相应的文件描述符被关闭之后自动释放。

如下代码都会释放建议性锁:

flock(fd, LOCK_EX);
flock(fd, LOCK_UN);
flock(fd, LOCK_EX);
fclose(fd);    //这种情况只试用于当前打开的文件只有一个fd指向它。

当一个文件描述符被复制时(dup()、dup2()、或一个fcntl() F_DUPFD操作),新的文件描述符会引用同一个文件锁。

flock(fd, LOCK_EX);
new_fd = dup(fd);
flock(new_fd, LOCK_UN);

这段代码先在fd上设置一个互斥锁,然后通过fd创建一个指向相同文件的新文件描述符new_fd,最后通过new_fd来解锁。从而我们可以得知新的文件描述符指向了同一个锁。所以,如果通过一个特定的文件描述符获取了一个锁并且创建了该描述符的一个或多个副本,那么,如果不显示的调用一个解锁操作,只有当文件描述符副本都被关闭了之后锁才会被释放。

同理,当fork()一个子进程后,子进程会复制父进程中的所有描述符,从而使得它们也会指向同一个文件锁。

flock (fd, LOCK_EX);

if (0 == fork ()) {
    flock (fd, LOCK_UN);
}

如上这段代码子进程也会释放父进程的文件锁。当然,如果文件描述符设置了close-on-exec标志且子进程执行了exec(),文件描述符被关闭,子进程不再拥有文件描述符情况除外。

4、建议性锁的限制

只能对整个文件进行加锁。这种粗粒度的加锁会限制协作进程间的并发。假如存在多个进程,其中各个进程都想同时访问同一个文件的不同部分。

通过flock()只能放置劝告式锁。

5、强制性锁

是OS内核的文件锁。每个对文件操作时,例如执行open、read、write等操作时,OS内部检测该文件是否被加了强制锁,如果加锁导致这些文件操作失败。也就是内核强制应用程序来遵守游戏规则;

注意:操作系统默认情况下使用的是建议性锁,所以在日常开发中执行文件IO先放一把建议性锁。

原文地址:https://www.cnblogs.com/alvin2010/p/8987708.html

时间: 2024-10-14 16:50:55

建议性锁和强制性锁的相关文章

Linux建议锁和强制锁

llinxu强制性锁默认是不开启的,想让linux支持强制性锁,不但在mount的时候需要加上-o mand,而且对 要加锁的文件也需要设置相关权限. 1.建议性锁业称为协同锁,对于这种类型的锁,内核知识提供加减锁以及检测是否加锁的操作,但是不提供锁的控制与 协同工作,也就是说,如果应用程序对某个文件进行操作时,没有检测是否加锁或者 无视加锁而直接向文件写入数据,内核是不会加以阻拦控制的.因此,建议锁,不能阻止进程对文件的操作, 而只能依赖于大家自觉的去检测是否加锁然后约束自己的行为: 2.强制

linux 建议锁和强制锁

作为APUE 14.3节的参考 linux是有强制锁的,但是默认不开启.想让linux支持强制性锁,不但在mount的时候需要加上-o mand,而且对要加锁的文件也需要设置相关权限. 1.??????????????建议锁又称协同锁.对于这种类型的锁,内核只是提供加减锁以及检测是否加锁的操作,但是不提供锁的控制与协调工作.也就是说,如果应用程序对某个文件进行操作时,没有检测是否加锁或者无视加锁而直接向文件写入数据,内核是不会加以阻拦控制的.因此,建议锁,不能阻止进程对文件的操作,而只能依赖于大

操作系统文件建议锁与强制锁

文件锁有建议使用和强制使用之分. 建议锁又称协同锁.对于这种类型的锁,内核只是提供加减锁以及检测是否加锁的操作,但是不提供锁的控制与协调工作.也就是说,如果应用程序对某个文件进行操作时,没有检测是否加锁或者无视加锁而直接向文件写入数据,内核是不会加以阻拦控制的.因此,建议锁,不能阻止进程对文件的操作,而只能依赖于大家自觉的去检测是否加锁然后约束自己的行为:多数 Unix 和类 Unix 操 作系统使用建议型锁,有些也使用强制型锁或兼而有之. 强制锁,是OS内核的文件锁.每个对文件操作时,例如执行

【锁】Oracle锁系列

[锁]Oracle锁系列 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 锁的概念.分类.及其模拟 ② 查询锁的视图及视图之间的关联 ③ 锁的参数(DML_LOCKS.DDL_LOCK_TIMEOUT) ④ FOR UPDATE及FOR UPDATE OF系列 ⑤ 带ONLINE和不带ONLINE创建索引的锁情况(是否阻塞DML操作) ⑥ 包或存过不能编译的解决方法

Hibernate学习---第十二节:Hibernate之锁机制&乐观锁实现

1.悲观锁 它指的是对数据被外界修改保持保守态度,因些,在整个数据处理过程中,将数据牌锁定状态.悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层的锁机制才能保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据). 一个典型的悲观锁调用示例: select * from account where name = "12345" for update 通过for update子句,这条SQL锁定了account表中所有符合检索条件的记录.本次事务

事务的乐观锁和悲观锁

Select -forupdate语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句也不会被其他类型语句所阻碍. 借助for update子句,我们可以在应用程序的层面手工实现数据加锁保护操作.本篇我们就来介绍一下这个子句的用法和功能. 从for update子句的语法状态图中,我们可以看出该子句分为两个部分:加锁范围子句和加锁行为子句.下面我们分别针对两个方面的进行介绍. 加锁范围子

MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)

本文参考: http://mysqlpub.com/thread-5383-1-1.html http://blog.csdn.net/c466254931/article/details/53463596 有很多是转载合并过来. 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的 计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数据库并发访问性能的一个重

乐观锁和悲观锁 你更钟情于哪一个?

链接:http://www.csdn.net/article/2012-12-12/2812708-leguansuo-beiguansuo-couchbase :云计算 对数据库的并发访问一直是应用程序开发者需要面对的问题之一,一个好的解 决方案不仅可以提供高的可靠性还能给应用程序的性能带来提升.下面我们来看一下Couchbase产品市场经理Don Pinto结合Couchbase Server为我们带来的悲观锁和乐观锁的解析. 故事背景:Alice和Joe将共同读取Couchbase Ser

第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种数据库自身体系结构的理解.今天这一讲,作为补充 Java 面试考察知识点的完整性,关于数据库的应用和细节还需要在实践中深入学习.今天我要问你的问题是,谈谈 MySQL 支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?典型回答所谓隔离级别(Isolation Level),就是在数据库事务中,