互斥体似乎没有锁定资源

问题描述 投票:0回答:1

我希望每当文件打开时,我的 go 例程都会从新文件中读取。为此,我使用互斥体来做到这一点。但输出似乎并没有达到预期。在 f1.txt 中我有

hello
,在 f2.txt 中我有
world
。我正在这两个文件之间切换。

type Root struct {
    File *os.File
    sync.RWMutex
}

func main() {
    startWorker()
}
func startTask(root *Root) {
    interval := 1 * time.Second
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    i := 0
    for {
        go func(i int, root *Root) {
            root.RLock()
            defer root.RUnlock()
            content, _ := io.ReadAll(root.File)
            fmt.Printf("go routine %v is reading data %s\n", i, content)
        }(i, root)
        i++
        <-ticker.C
    }
}
func startWorker() {

    interval := 4 * time.Second
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    f1 := "concurrent/1/f1.txt"
    f2 := "concurrent/2/f2.txt"

    f := f1
    file, _ := os.Open(f)
    root := &Root{File: file}

    go startTask(root)
    for {
        root.Lock()
        if f == f2 {
            f = f1
        } else {
            f = f2
        }
        root.File.Close()
        file, _ := os.Open(f)
        root.File = file
        root.Unlock()
        <-ticker.C
    }
}

输出看起来如下

go routine 0 is reading data world
go routine 1 is reading data 
go routine 2 is reading data 
go routine 3 is reading data 
go routine 4 is reading data hello
go routine 5 is reading data 
go routine 6 is reading data 
go routine 7 is reading data 
go routine 8 is reading data world
go routine 9 is reading data 
go mutex goroutine
1个回答
0
投票

问题在于

io.ReadAll(root.File)
读取到文件末尾,而后续读取结果为空。通过在读取之前查找文件的开头来修复。

    go func(i int, root *Root) {
        root.RLock()
        defer root.RUnlock()
        root.File.Seek(0, os.SEEK_SET)
        content, _ := io.ReadAll(root.File)
        fmt.Printf("go routine %v is reading data %s\n", i, content)
    }(i, root)

在 Go Playground 上尝试一下!.

© www.soinside.com 2019 - 2024. All rights reserved.