(tandard c libraries translation )flock

flock - apply or remove an advisory lock on an open file
flock - 添加或者移除咨询性文件锁

所需头文件
#include <sys/file.h>

int flock(int fd, int operation);

Apply or remove an advisory lock on the open file specified by fd.  The argument operation is one of the following:
添加或者一处咨询性锁到fd所关联的文件,operation参数如下:
LOCK_SH  Place a shared lock.  More than one process may hold a shared lock for a given file at a given time.
添加一个共享锁,多个进程可以在给定时间持有给定文件的共享锁
LOCK_EX  Place an exclusive lock.  Only one process may hold an exclusive lock for a given file at a given time.
添加一个互斥锁,只有一个进程可以在给定的时间持有给定文件的互斥锁
LOCK_UN  Remove an existing lock held by this process.
移除当前进程所持有的锁

A  call to flock() may block if an incompatible lock is held by another process.  To make a nonblocking request, include LOCK_NB (by ORing) with any of the above operations.
调用flock可能会阻塞,如果互斥锁被其他进程持有,为了使调用非阻塞,使用LOCK_NG和上面参数做或操作

A single file may not simultaneously have both shared and exclusive locks.
单个文件不允许同时持有共享锁和互斥锁

Locks created by flock() are associated with an open file table entry.  This means that duplicate file descriptors (created by, for example, fork(2) or dup(2))  refer to the same lock, and this lock may be modified or released using any of these descriptors.  Furthermore, the lock is released either by an explicit LOCK_UN operation on any of these duplicate descriptors, or when all such descriptors have been closed.
flock所创建的锁都需要关联打开的文件表条目,这就是说文件描述符副本(通过fork或者dup所创建)拥有相同的锁,这个锁可以被这些文件描述符修改和释放,另外,锁的释放可以通过任何一个文件描述符副本显示调用LOCK_UN操作来完成,或者所有的这些文件描述符都被关闭

If a process uses open(2) (or similar) to obtain more than one descriptor for the same file, these descriptors are treated  independently  by  flock(). An  attempt  to  lock  the  file  using  one  of these file descriptors may be denied by a lock that the calling process has already placed via another descriptor.
如果一个进程通过open(或者类似的操作)来获取同一个文件超过一个文件描述符,这些描述符会被flock单独对待,这些文件描述符中的一个试图锁住文件都会被拒绝,因为会被另一个进程的文件描述符锁住

A process may only hold one type of lock (shared or exclusive) on a file.  Subsequent flock() calls on an already locked file will convert an  existing lock to the new lock mode.
一个进程对于同一个文件来说只能持有一种锁,后续在已经锁住的文件上调用flock会把已经存在的锁转换成新的模式的锁

Locks created by flock() are preserved across an execve(2).
flock所创建的锁通过execve来保存

A shared or exclusive lock can be placed on a file regardless of the mode in which the file was opened.
共享锁和互斥锁可以在不用考虑打开模式的情况下锁住文件

On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.
成功的时候返回0,失败的时候返回-1,errno被设置成合适的值

EBADF  fd is not an open file descriptor.
fd不是一个打开的文件描述符
EINTR  While waiting to acquire a lock, the call was interrupted by delivery of a signal caught by a handler; see signal(7).
在等待获取锁的时候,调用被信号中断
EINVAL operation is invalid.
操作是非法的
ENOLCK The kernel ran out of memory for allocating lock records.
分配锁的时候内存不足
EWOULDBLOCK  The file is locked and the LOCK_NB flag was selected.
这个文件已经被锁住,而且使用了LOCK_NB

flock()  does  not lock files over NFS.  Use fcntl(2) instead: that does work over NFS, given a sufficiently recent version of Linux and a server which supports locking.
flock不能在NFS上锁住文件,需要使用fcntl,fcntl在NFS上能够正常工作,使用支持锁的最新的linux版本和服务器

Since kernel 2.0, flock() is implemented as a system call in its own right rather than being emulated in the GNU C library as a call to fcntl(2).  This yields true BSD semantics: there is no interaction between the types of lock placed by flock() and fcntl(2), and flock() does not detect deadlock.
在kernel2.0以后,flock作为一个系统调用实现,而不是在GNU C库中使用fcntl来模拟实现,这个在BSD的协议中也有实现,也就是说flock和fcntl两种锁从此没有交互,而且flock不检测死锁

flock() places advisory locks only; given suitable permissions on a file, a process is free to ignore the use of flock() and perform I/O on the file.
flock只能处理咨询性锁,确保合适的文件权限,进程可以忽略掉flock的文件锁

flock() and fcntl(2) locks have different semantics with respect to forked processes and dup(2).  On systems that implement flock() using fcntl(2), the semantics of flock() will be different from those described in this manual page.
flock和fcntl锁对于fork出来的进程和dup遵守不同的规则,在某些flock是通过fcntl实现的系统上,flock的规则跟这里的会有所不同

Converting a lock (shared to exclusive, or vice versa) is not guaranteed to be atomic: the existing lock is first removed,  and  then  a  new  lock  is established.   Between these two steps, a pending lock request by another process may be granted, with the result that the conversion either blocks, or fails if LOCK_NB was specified.  (This is the original BSD behavior, and occurs on many other implementations.)

转换锁(共享锁转换成互斥锁)并不能保证原子性,存在的锁被删除掉,持有新的锁,在这两个步骤之间,另外一个进程后面的锁操作可能会生效,那么结果会阻塞住,如果使用了LOCK_NB选项,则会直接返回错误


testcase如下:

打开一个文件,锁住60s,然后解锁

#include <stdio.h>
#include <sys/file.h>
#include <string.h>
#include <errno.h>

int main(void)
{
	int fd;
	if ((fd = open("1.txt", O_RDWR)) == -1) {
		printf("open error: %s\n", strerror(errno));
		return -1;
	}
	if (flock(fd, LOCK_UN|LOCK_NB) != 0) {
		printf("unlock error: %s\n", strerror(errno));
		return -1;
	}
	if (flock(fd, LOCK_EX|LOCK_NB) != 0) {
		printf("flock error: %s\n", strerror(errno));
		return -1;
	}
	printf("i'm locking\n");
	sleep(60);
	flock(fd, LOCK_UN);
	printf("i'm unlocking\n");
	sleep(60);
	return 0;
}

打开一个文件,在文件尾部写入\nhello,正常的用法是需要先拿到锁,然后再操作,不然的话是可以直接写入的,这样子就失去了锁的作用,这里我没有使用LOCK_NB参数,这样子的拿不到锁的时候会阻塞住,直到拿到锁

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(void)
{
	int fd;
	if ((fd = open("1.txt", O_RDWR)) == -1) {
		printf("open error: %s\n", strerror(errno));	
		return -1;
	}
	printf("locking file\n");
	flock(fd, LOCK_EX);
	printf("locked file\n");
	lseek(fd, 0, SEEK_END);
	write(fd, "\nhello", 6);
	fsync(fd);
	flock(fd, LOCK_UN);
	close(fd);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值