2020-08-24

vue3的面试题 阅读详情

转载[https://blog.youkuaiyun.com/guotianqing/article/details/80044087]

1. 概述

  在多数unix系统中,当多个进程/线程同时编辑一个文件时,该文件的最后状态取决于最后一个写该文件的进程。

  对于有些应用程序,如数据库,各个进程需要保证它正在单独地写一个文件。这时就要用到文件锁。

  文件锁(也叫记录锁)的作用是,当一个进程读写文件的某部分时,其他进程就无法修改同一文件区域。

  能够实现文件锁的函数主要有2个:flock和fcntl。

  早期的伯克利版本只支持flock,该函数只能对整个文件加锁,不能对文件的一部分加锁。

  lockf是在fcntl基础上构造的函数,它提供了一个简化的接口。它们允许对文件中任意字节区域加锁,短至一个字节,长至整个文件。

1.1 fcntl函数

#include <fcntl.h>

int fcntl(int fd, int cmd, .../*struct flock *flockptr*/);
#返回值:若成功,返回值依赖于cmd,失败返回-1

  cmd是F_GETLK, F_SETLK, F_SETLKW中的一个。第三个参数是指向flock结构的指针,flock结构如下:

struct flock {
    short l_type;/* one of F_RDLCK, F_WRLCK, F_UNLCK */
    short l_whence;/* SEEK_SET, SEEK_CUR, SEEK_END */
    off_t l_start;/* offset in bytes, relative to l_whence */
    off_t l_end;/* length, in bytes, 0 means lock to EOF */
    off_t l_pid;/* returned with F_GETLK */
};
  • 锁类型:共享读锁F_RDLCK,独占性写锁F_WRLCK,解锁F_UNLCK
  • 加锁或解锁区域的起始字节偏移量(l_start, l_whence)
  • 区域字节长度(L_len)
  • 进程的id持有的锁能阻塞当前进程,仅由F_GETLK返回
  • 锁可以在文件尾处开始或者越过尾端开始,但是不能在文件起始位置之前开始
  • 若l_len=0, 表示锁的范围可以扩大到最大可能偏移量,这意味着不管向文件中追加多少数据,它们都可以处于锁的范围内,而且起始位置可以任意
  • 设置l_start和l_whence指向文件的起始位置,并且指定l_len=0,以实现对整个文件加锁(一般l_start=0, l_whence=SEEK_SET)

2. 锁的使用

2.1. 使用锁的基本规则:

  • 任意多个进程在一个给定的字节上可以有一把共享的读锁(F_RDLCK),但是在一个给定的字节上只能有一个进程有一把独占性写锁(F_WRLCK)。
  • 如果在一个给定字节上已经有一把或多把读锁,则不能在该字节上再加写锁,如果在一个字节上已经有一把独占性写锁,则不能再对它加任何读锁。
  • 对于单个进程而言,如果进程对某个文件区域已经有了一把锁,然后又试图在相同区域再加一把锁,则新锁会替换旧锁。
  • 加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开。

2.2. fcntl三种cmd的使用:

  • F_GETLK:判断由flockptr所描述的锁是否会被另一把锁所排斥(阻塞),如果存在一把锁阻止创建由flockptr所描述的锁,由该现有锁的信息将重写flockptr指向的信息。如果不存在这种情况,则除了将l_type设置为F_UNLCK之处,flockptr所指向结构中的其他信息保持不变。
  • F_SETLK:设置由flockptr所描述的锁,如果程序试图获得一把锁,而系统阻止程序获得该锁,则fcntl会立即返回错误,errno设置为EACCES或EAGAIN。当l_type=F_UNLCK时,此命令用来清除指定的锁。
  • F_SETLKW:F_SETLK的阻塞版本(wait)。如果程序尝试获得的锁无法被授予,调用进程会进入休眠直到进程获得锁或者信号中断。

  注意:用F_GETLK测试能否创建一把锁,然后用F_SETLK尝试建立锁之间并非原子操作,也就是说两次调用之间有可能另一进程插入并创建了相同的锁。如果不希望在等待锁变为可用时产生阻塞,就必须处理由F_SETLK返回的可能出错值。

#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <fcntl.h>

pid_t lock_test(int fd, int type, off_t offset, int whence, off_t len)
{
    struct flock lock;

    lock.l_type = type;
    lock.l_start = offset;
    lock.l_whence = whence;
    l   ock.l_len = len;

    if (fcntl(fd, F_GETLK, &lock) < 0) {
        printf("fcntl error: %s\n", strerror(errno));
        return 1;
    }

    if (lock.l_type == F_UNLCK) {
        return 0;
    }

    return lock.l_pid;
}

2.3. 锁的继承与释放

锁的继承和释放有以下三条原则:

  • 锁与进程和文件两者相关联。即当一个进程终止时,它所建立的所有锁均释放,对于描述符而言,无论它何时关闭,进程通过它引用的文件上的任何一把锁也都会释放。
  • 由fork产生的子进程不继承父进程所设置的锁。
  • 执行exec后,新程序可以继承原程序的锁。注意,如果对一个文件描述符设置了执行时关闭标志,那么当作为exec的一部分关闭该文件描述符时,将释放相应文件的所有锁。

2.4. 避免死锁

  如果两个进程互相等待对方持有并且不释放的资源时,这两个进程就会进入死锁状态。

  如果一个进程已经控制了文件中的一个加锁区域,然后它又试图对另一个进程控制的区域加锁,那么它就会进入睡眠,并有可能发生死锁。

  检测到死锁时,内核必须选择一个进程接收错误返回。

RPCA模型及GoDec算法 一、基础知识 在线性代数中,秩的物理意义是矩阵中最大的不相关的向量个数,因此秩可以用来度量相关性;而在图像处理中,秩就可以理解为图像中所包含的信息的丰富程度。图片中比较突兀的成分,会增加图像矩阵的秩,一幅清晰的自然图像其数据矩阵往往是低秩或者近似低秩的,这是因为其中的图像信息有很大的相关性,但如果图像中引入噪声,那么存在随机幅值任意大但是分布稀疏的误差破坏了原有数据的低秩性。 低秩矩阵:如果AAA是一个m×nm×nm×n的矩阵,rank(A)rank(A)rank(A)是矩阵AAA的秩,如果rank(A) 阅读详情

相关推荐

⭐️白嫖的阿里云认证⭐️ 【真题&参考答案】:大模型Clouder认证:利用大模型提升内容生产能力

【摘要】真题「大模型Clouder认证:利用大模型提升内容生产能力」

davidkorhenn的博客 1921

108-记录锁(继承与释放)

1. 释放 如果进程关闭,所有的记录锁都被释放 任何一个描述符关闭,该描述符引用的文件上的任何记录都被释放。 有关上面两点,实际上在上一篇文章就已经解释过了,对于同一个文件来说,无论你是 open 还是 dup 多少次,vnode 节点始终只有一份,而锁的信息是在 vnode 节点中保存。2. 继承 fork 产生的子进程不继承父进程所设置的锁。 这种约束是有依据的:因为记录锁的作用就是阻止多个进程

进击的小学生 1428

实例讲解CANoe报文解析使用方法

在日常工作中,经常需要分析车辆产生故障的原因,在电动汽车中,分布式控制器及线束在其中某一个地方出现问题,就有可能造成车辆故障,但是由于电气零件无法直观的观察到哪个部位发生了故障,所以要借助工具测量电气变量或者采集报文信息通过分析,解析出故障原因,从而为车辆的开发,测试,维修提供支持。其中汽车行业最通用的通讯方式就是CAN通讯,本文针对使用CANoe对CAN报文离线分析的使用方法做详细介绍。

qq_43011586的博客 1万+

Lock,LockFree,MemoryBarrier,ConcurrentCollection

最近看并行编程书本的一些心得,简单记录下多线程和并行编程必知必会的几个概念,再次加深自己的理解。 .NET Framework4提供了一个新的命名空间System.Collections.Concurrent用于解决常用集合在并发情况下的线程安全问题(ps:通过这个命名空间还可以访问用于并行化循环和PLINQ的自定义分区器Partitioner)。这个命名空间下的所有线程安全集合都在某种程度上使...

weixin_34399060的博客 170

RT-Thread stm32h7使用串口DMA

stm32h7在rtthread中无法使用串口DMA,通过更改驱动代码使其支持串口DMA

qq_35141454的博客 2284

华为od 面试八股文_Spring_03_含答案

控制反转IOC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找依赖注入;

MISAYAONE的博客 2335

两个线程交替打印1-100

线程之间的通信基本的三个方法: wait():一旦执行该方法,当前线程就会堵塞状态,并释放同步监视器(锁) notify():一旦执行该方法,就会唤醒被wait的一个线程,如果是多个,则唤醒优先级高的线程 notifyAll():一旦执行该方法,就会唤醒所有被wait的线程 使用 synchronized 和 wait notify 来实现两个线程交替打印: public class TestPrintNumber { public static void main(String[] args)

一路的博客 1万+

CAM350常用快捷键

CAM350快捷键 CAM350常用快捷键

bhxc809751502的博客 3052
上一篇: c++异常机制--学习笔记
BERLIN23
博客等级 码龄14年 7粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值