文件锁(三)——文件锁的原理

本文深入解析文件锁的工作机制,阐述如何通过文件锁实现进程间的互斥与共享访问。文章详细解释了读锁与写锁之间的关系,以及它们如何在锁链表中表示,帮助读者理解文件锁是如何协调不同进程对同一文件的并发访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件锁的原理

理解了文件锁的原理后,就可以理解为什么文件锁可以实现互斥与共享了。

若A进程与B进程同时打开同一个文件,他们使用同一个文件表,使用同一个V节点,V节点指向hello这个文件,里面有一个锁链表,里面记录了锁的信息。

加锁时,进程会检查共享的文件锁链表

  1. 如果链表上只有读锁节点
    • 所有目前其他进程对该文件只加了读锁,由于读锁时共享的,所以不管链表上有几个读节点,当前进程都能成功加读锁。
    • 图:
    • 提供:链表上可不可以存在n多个读锁节点?
    • 答:可以,因为读锁是共享的,不管别的进程有没有解读锁,所有进程都可以加读锁,每加一个读锁,链表上就多一个读锁节点,只有当解锁时节点才被删除。
  2. 如果链表上有一个写锁节点
    • 表明,当前有进程对文件加了锁,锁节点还存在,表示人家目前还没有解锁,写锁是互斥的,所以当前不能加读锁,别人解锁后才能加读锁,加锁后链表上就插入了一个读锁节点。
    • 没有解锁就表示数据没有写完,必须等到解锁后才能加读锁
    • 提问:链表上可不可能同时存在多个写锁节点?
    • 答:不可能,因为写锁是互斥的,目前只有一个进程再给文件加写锁,再解锁之前,别的进程不能加写锁。
    • 疑问:链表上会不会同时存在读锁节点和写锁节点?
    • 读锁节点和写锁节点也是互斥的,链表上有读锁节点就不可能存在写锁节点,反过来有写锁节点就不能有读锁节点。

如果你想加锁?

  1. 如果链表上有读锁节点,别人没有解锁,读锁与写锁互斥,不能加写锁。
  2. 如果链表上有写锁节点,被人没有解锁,写锁与写锁互斥,多以当前进程不能加写锁。

对比进程信号量?

  1. 进程信号量:进程间共享信号量集合,通过检查集合中信号量的值,从而知道自己能不能操作
  2. 文件锁:进程共享文件锁链表,通过检查链表上的锁节点,从而知道自己能不能操作。

文件锁其他值得注意的地方

  • 在同一进程中,如果多个文件描述符指向同一文件,只要关闭其中任何一个文件描述符,那么该进程加在文件上的文件锁将会被删除,也就是该进程在"文件锁链表"上的“读锁写锁”节点会被删除。
  • 进程终止时会关闭所有打开的文件描述符,所以进程结束时会自动删除所有加的文件锁。
  • 父进程所加的文件锁,子进程不会继承,我们在讲进程控制时就说过加锁是进程各自私人事情,不能继承,就好比你爸有癌症,你也会有吗?

一个值得理解的问题:多线程之间能不能使用文件锁?

可以,但是线程不能使用同一个open返回的文件描述符,线程必须使用自己open所得到的文件描述符才有效。

代码演示:

线程使用要自己打开文件描述符

void *pth_fun(void *pth_arg)
{
	int fd;

	fd = open("./hello", O_RDWR|O_CREAT|O_TRUNC, 0664);
	if (fd == -1)  print_err("./hello", __LINE__, errno); 
	while(1)
	{
		SET_WRFLCKW(fd, SEEK_SET, 0, 0);
		write(fd, "hello ", 6);
		write(fd, "world\n", 6);
		SET_UNFLCK(fd, SEEK_SET, 0, 0);
	}
	return NULL;
}

int main(int argc, char *argv[])
{
	int fd = -1;
	int ret = -1;
	pthread_t tid;

	fd = open("./hello", O_RDWR|O_CREAT|O_TRUNC, 0664);
	if (fd == -1)  print_err("./hello", __LINE__, errno); 

	ret = pthread_create(&tid, NULL, pth_fun, NULL);
	if (ret == -1) print_err("pthread_create fail", __LINE__, ret);

	while(1)
	{
		SET_WRFLCKW(fd, SEEK_SET, 0, 0);
		write(fd, "hello ", 6);
		write(fd, "world\n", 6);
		SET_UNFLCK(fd, SEEK_SET, 0, 0);
	}
  
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值