golang文件锁

1 篇文章 0 订阅
1 篇文章 0 订阅

在Go语言中实现对同一个文件的写抢占,意味着你需要确保在任何给定时间点,只有一个goroutine(或者进程)能够写入文件。这通常通过文件锁来实现。下面是一个使用之前提到的gofrs/flock库来实现文件写操作抢占的示例。

这个示例将演示如何在多个goroutine中对同一文件进行写操作,但确保每次只有一个goroutine能写入。

首先,确保你已经安装了gofrs/flock库:

go get github.com/gofrs/flock

然后,你可以创建一个程序如下:

package main

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

// writeFile尝试获取文件锁并写入数据
func writeFile(id int, wg *sync.WaitGroup, lock *flock.Flock) {
    defer wg.Done()

    // 尝试获取锁
    locked, err := lock.TryLock()
    if err != nil {
        fmt.Printf("Goroutine %d: 错误 - %s\n", id, err)
        return
    }

    if !locked {
        fmt.Printf("Goroutine %d: 未能获取锁,跳过\n", id)
        return
    }

    // 拿到锁后写入文件
    fmt.Printf("Goroutine %d: 获取到了锁\n", id)
    file, err := os.OpenFile(lock.Path(), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        fmt.Printf("Goroutine %d: 打开文件错误 - %s\n", id, err)
        return
    }
    defer file.Close()

    _, err = file.WriteString("Goroutine " + strconv.Itoa(id) + " was here.\n")
    if err != nil {
        fmt.Printf("Goroutine %d: 写文件错误 - %s\n", id, err)
        return
    }

    // 完成后解锁
    if err := lock.Unlock(); err != nil {
        fmt.Printf("Goroutine %d: 解锁失败 - %s\n", id, err)
        return
    }
    fmt.Printf("Goroutine %d: 写入并解锁成功\n", id)
}

func main() {
    var wg sync.WaitGroup
    lock := flock.New("test.lock")

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go writeFile(i, &wg, lock)
        // 为了更好地观察竞争情况,这里我们在启动goroutine之间故意加入短暂的睡眠
        time.Sleep(100 * time.Millisecond)
    }

    wg.Wait()
    fmt.Println("所有goroutine完成")
}

这个程序创建了5个goroutine,每个goroutine都尝试对同一个文件加锁,并在成功获取锁之后写入一些信息。通过gofrs/flock库,我们可以确保同一时间只有一个goroutine能够写入文件,从而避免了写入操作的竞争条件。

请注意,执行这段代码时,你可能会看到并不是所有goroutine都能成功写入文件。这是因为如果一个goroutine已经持有了锁,其他尝试获取锁的goroutine将不能获取锁,因此会跳过写入操作。这种机制确保了文件写入的互斥性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值