记录锁(record locking)机制

要讲解记录锁机制,首先要介绍fcntl函数,如下给出该函数原型:

#include <fcntl.h>

int fcntl(int filedes, int cmd, ... /* struct flock *flockptr */)

函数返回值:若成功则依赖于cmd,若出错则返回-1。

对于记录锁,cmd是F_GETLK, F_SETLOCK, F_SETLKW。第三个参数(称其为flockptr)是一个指向flock结构的指针:

struct flock {
short l_type;    /* F_RDLCK, F_WRLCK, or F_UNLCK */
off_t l_start;    /* offset in bytes, relative to l_whence */
short l_whence;    /* SEEK_SET, SET_CUR, or SEEK_END */
off_t l_len;    /* length, in bytes; 0 means lock to EOF */
pid l_pid;    /* returned with F_GETLK */
};

对flock结构说明如下:

  • 所希望的锁类型:F_RDLCK(共享读锁),F_WRLCK(独占性写锁) 或则 F_UNLCK(解锁一个区域)
  • 要加锁或解锁区域的起始字节偏移,这由l_start和l_whence两者决定。
  • 区域的字节长度,由l_len表示。
  • 具有能阻塞当前进程的锁,其持有进程的ID存放在l_pid中(仅由F_GETLK返回)。

关于加锁和解锁区域的说明还要注意下列各点:

  • l_stat是相对偏移量(字节),l_whence则决定了相对偏移量的起点。这与lseek函数中最后两个参数类似。
  • 该区域可以在当前文件尾端处开始或越过其尾端处开始,但是不能在文件起始位置之前开始。
  • 如若l_len为0,则表示锁的区域从其起点(由l_start和l_whence两者决定)开始直至最大可能偏移量为止,也就是不管添写到该文件中多少数据,它们都在锁的范围内(不必猜测会有多少字节被追加到文件之后)。
  • 为了锁整个文件,我们设置l_start和l_whence,使锁的起点在文件起始处,并且说明长度(l_len)为0

以下说明fcntl函数的三种命令:

F_GETLK:判断由flockptr锁描述的锁是否会被另外一把锁所排斥(阻塞)。如果存在一把锁,它阻止创建由flockptr所描述的锁,则把该现存锁的信息写到flockptr指向的结构中如果不存在这种情况,则将l_type设置为F_UNLOCK外,flockptr所指向结构的其他信息保持不变。

F_SETLK:设置由flockptr所描述的锁。如果试图建立一把读锁(l_type设为F_RDLCK)或写锁(l_type设为F_WRLCK),而按兼容性规则不能允许的情况,fcntl立即出错返回,此时errno设置为EACCES或EAGAIN。此命令也用来清除由flockptr说明的锁(l_type为F_UNLCK)。

F_SETLKW:这是F_SETLK的阻塞版本。如果因为当前在请求区间的某个部分另一个进程已经有一把锁,因而按兼容性规则由flockptr所请求的锁不能被创建,则使调用进程休眠。如果请求创建的锁已经可用,或者休眠由信号中断,则该进程被唤醒。

实际编程中,为了避免每次分配flock结构,然后又填入各项信息,可以用如下函数两处理所有这些细节:

#include <fcntl.h>

int
lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
	struct flock	lock;

	lock.l_type = type;		/* F_RDLCK, F_WRLCK, F_UNLCK */
	lock.l_start = offset;	/* byte offset, relative to l_whence */
	lock.l_whence = whence;	/* SEEK_SET, SEEK_CUR, SEEK_END */
	lock.l_len = len;		/* #bytes (0 means to EOF) */

	return(fcntl(fd, cmd, &lock));
}

其他的加读、写或解文件锁的操作就可以定义为如下的宏:

#define	read_lock(fd, offset, whence, len) 			lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define	readw_lock(fd, offset, whence, len) 			lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
#define	write_lock(fd, offset, whence, len) 			lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
#define	writew_lock(fd, offset, whence, len) 			lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define	un_lock(fd, offset, whence, len) 			lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))

记录锁(record locking)机制,布布扣,bubuko.com

时间: 2024-12-07 02:59:46

记录锁(record locking)机制的相关文章

乐观锁(optimistic locking)与悲观锁(pessimistic locking)

首先,乐观锁(optimistic locking)与悲观锁(pessimistic locking)基本是针对数据处理来说,也就是跟数据库有关的术语,目的是为了解决并发处理时所遇到的相关性能问题,以避免数据丢失更新. 悲观锁(pessimistic locking):指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态,以保证操作最大程度的独占性,当然也就给数据库增加了大量开销降低了性能.一般依靠数据库提供的锁

MySQL锁的管理机制

转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/48805847 ********************************** ********************************** MySQL server层面的一些锁? table-level locking(表级锁) ? page-level locking(页级锁) ? row-level locking(行级锁)-----------------------

详解 MySql InnoDB 中的三种行锁(记录锁、间隙锁与临键锁)

详解 MySql InnoDB 中的三种行锁(记录锁.间隙锁与临键锁) 前言 InnoDB 通过 MVCC 和 NEXT-KEY Locks,解决了在可重复读的事务隔离级别下出现幻读的问题.MVCC 我先挖个坑,日后再细讲,这篇文章我们主要来谈谈那些可爱的锁. 什么是幻读? 幻读是在可重复读的事务隔离级别下会出现的一种问题,简单来说,可重复读保证了当前事务不会读取到其他事务已提交的 UPDATE 操作.但同时,也会导致当前事务无法感知到来自其他事务中的 INSERT 或 DELETE 操作,这就

salesforce 零基础学习(三十六)通过Process Builder以及Apex代码实现锁定记录( Lock Record)

上一篇内容是通过Process Builder和Approval Processes实现锁定记录的功能,有的时候,往往锁定一条记录需要很多的限制条件,如果通过Approval Processes的条件判断写起来可能很麻烦,有些逻辑通过Apex写起来很容易,此篇内容为通过Process Builder 和Apex代码实现锁定记录. 需求:对Opportunity表进行判断是否加锁或者解锁.当Delivery/Installation Status这一项的值为'Completed'情况下加锁,为其他

记录锁

记录锁的功能是:当一个进程正在读或修改文件的某个部分时,它可以阻止其它进程修改同一文件区.fcntl函数可以实现这一功能. #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); 对于记录锁,cmd是F_GETLK.F_SETLK或F_SETLKW,第三个参数是一个指向flock结构的指针: struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK,

Linux环境编程之高级I/O(一):非阻塞I/O、记录锁

引言:高级I/O包括非阻塞I/O.记录锁.系统V流机制.I/O多路转接(select和poll函数).readv和writev函数以及存储映射I/O. (一)非阻塞I/O 可能会使进程永远阻塞的一类系统调用有: 1.如果某些文件类型的数据并不存在,则读操作可能会使调用者永远阻塞. 2.如果数据不能立即被上述同样类型的文件接受,则写操作也会使调用者永远阻塞. 3.在某种条件发生之前,打开某些类型的文件会阻塞. 4.对已经加上强制记录锁的文件进行读.写. 5.某些ioctl操作. 6.某些进程间通信

JVM内部细节之一:synchronized关键字及实现细节(轻量级锁Lightweight Locking)

在C程序代码中我们可以利用操作系统提供的互斥锁来实现同步块的互斥访问及线程的阻塞及唤醒等工作.然而在Java中除了提供Lock API外还在语法层面上提供了synchronized关键字来实现互斥同步原语.那么到底在JVM内部是怎么实现synchronized关键子的呢? 一.synchronized的字节码表示: 在java语言中存在两种内建的synchronized语法:1.synchronized语句:2.synchronized方法.对于synchronized语句当Java源代码被ja

SQL Server 锁的排队机制

1.新建一个表,插入1010000数据: create table test(id int identity(1,1) ,name varchar(600)) go insert into test values(replicate('a',600)); go 1010000 create index idx_test_id on test(id) 2.新开一个会话(A),运行如下语句,由于没有提交,所以会阻塞其他药修改相同数据的会话: begin tran update test set na

unix 中的记录锁

如果一个文件被两个人同时修改会出现什么结果呢?在很多unix系统中,该文件的最后状态取决于写该文件的最后一个进程.但是对于有些应用程序(例如数据库),进程有时需要确保它正在单独写一个文件.为了向进程提供这种功能,商用unix系统提供了记录锁机制. 记录锁的功能是:当一个进程正在读或修改文件的某个部分时,它可以组织其他进程修改同一文件区.对于unix系统而言,"记录"这个次是一种误会,因为unix系统内核根本没有使用文件记录这种概念.更适合的术语可能是"字节范围锁",