flock.md

flock

本教程旨在帮助开发者和系统管理员了解如何使用 flock 命令来管理文件锁定,从而避免文件在多个进程之间的竞争条件。通过阅读本教程,读者将能够学会如何使用 flock 实现文件锁定,并掌握一些实际应用场景。

为什么要学习这个教程?

在开发和系统管理中,多个进程可能会同时访问和修改同一个文件,导致数据不一致或文件损坏。使用 flock 可以有效地防止这些问题,确保文件操作的原子性和一致性。
同时也可以依赖此机制实现进程间读写锁机制

教程大纲

在本教程中,将学习如何:

  • 使用 flock 命令对文件进行锁定
  • 在脚本中应用 flock 以确保文件操作的安全

在开始之前

请确保已具备以下条件:

  • 在系统上已安装 flock 命令。大多数 Linux 发行版默认包含 flock,如果没有,可以通过包管理器安装。
  • 具备基本的 Linux 命令行操作知识。

第1部分

在第一部分,将学习如何使用 flock 命令来实现文件锁定。

  1. 在终端中执行以下命令,创建一个测试文件:

    1
    echo "测试内容" > /tmp/testfile
  2. 使用 flock 命令对文件进行锁定,执行以下命令:

    1
    flock -x /tmp/testfile -c 'echo "文件已锁定"'

    该命令会对 /tmp/testfile 进行独占锁定,并执行 echo "文件已锁定" 命令。锁定期间,其他进程将无法获得该文件的独占锁。

  3. 尝试在另一个终端中对同一文件进行锁定,验证锁定效果:

    1
    flock -x /tmp/testfile -c 'echo "另一个进程尝试锁定"'

    由于文件已被锁定,第二个 flock 命令将等待,直到第一个命令释放锁。

第2部分

在第二部分,将学习如何在脚本中使用 flock 实现安全的文件操作。

  1. 创建一个示例脚本 script.sh,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash
    exec 200>/tmp/testfile.lock
    flock -x 200

    echo "开始执行安全的文件操作"
    sleep 10
    echo "文件操作完成"

    flock -u 200
  2. 确保脚本具有执行权限:

    1
    chmod +x script.sh
  3. 在终端中执行脚本:

    1
    ./script.sh

    该脚本首先在文件 /tmp/testfile.lock 上创建一个文件描述符 200,然后对该描述符进行独占锁定。执行完文件操作后,释放锁定。

总结 {id=”what-learned”}

通过完成本教程,读者学会了如何使用 flock 命令对文件进行锁定,以确保多个进程对同一文件的访问不发生冲突。同时,读者还掌握了在脚本中应用 flock 进行安全文件操作的方法。

- [Linux `flock` 命令手册](https://man7.org/linux/man-pages/man1/flock.1.html) - [如何在 Bash 脚本中使用文件锁](https://www.cyberciti.biz/faq/linux-file-locking-using-flock-command/)

附录 golang flock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package flock

import (
"fmt"
"github.com/gofrs/flock"
"log"
"os"
"time"
)

func Case() {
f := flock.New(os.TempDir() + "/go-lock.lock")
lock, err := f.TryLock()
go func() {
log.Println("2:---")
f2 := flock.New(os.TempDir() + "/go-lock.lock")
time.Sleep(1 * time.Second)
l := f2.Locked()
log.Printf("2:--- : %v", l)
// todo 试试 未获取到锁的情况下进行写入 case
}()
if err != nil {
fmt.Printf("lock error: %v\n", err)
return
}
file, err := os.OpenFile(os.TempDir()+"/go-lock.lock", os.O_RDWR, 0600)
if err != nil {
fmt.Printf("open file error: %v\n", err)
}
defer file.Close()
_, err = file.WriteString("Hello, world!")
if err != nil {
// 写入错误处理
}

log.Printf("%v\n", lock)
time.Sleep(20 * time.Second)
log.Printf("locked: %v\n", f.Locked())
f.Unlock()
log.Printf("locked: %v\n", f.Locked())
}


flock.md
https://abrance.github.io/2024/05/16/mdstorage/domain/linux/flock/
Author
xiaoy
Posted on
May 16, 2024
Licensed under