首页 > 解决方案 > golang 中的 os.File.Write() 线程安全吗?

问题描述

当两个 Goroutines 同时写入文件时,它是线程安全的os.File.Write()吗?

根据this question Is os.File's Write() threadsafe?,它不是线程安全的。但是,以下代码的输出文件./test.txt没有出现错误。

并且根据这个问题Safe to have multiple processes write to the same file at the same time? [CentOs 6, ext4],POSIX “原始” IO 系统调用是线程安全的。os.File.Write()使用 POSIX IO 系统调用,所以我们可以说它是线程安全的吗?

package main

import (
    "fmt"
    "os"
    "sync"
)

func main() {
    filePath := "./test.txt"

    var wg sync.WaitGroup
    wg.Add(2)

    worker := func(name string) {
        // file, _ := os.Create(filePath)
        file, _ := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE, 0666)
        defer file.Close()
        defer wg.Done()
        for i := 0; i < 100000; i++ {
            if _, err := file.Write([]byte(name + ": is os.File.Write() thread safe?\n")); err != nil {
                fmt.Println(err)
            }
        }
    }

    go worker("worker1")
    go worker("worker2")

    wg.Wait()
}

标签: linuxmultithreadinggoposix

解决方案


文档没有明确说它是线程安全的。

虽然查看 Go 1.16.5 版本的源代码:

// Write implements io.Writer.
func (fd *FD) Write(buf []byte) (int, error) {
    if err := fd.writeLock(); err != nil {
        return 0, err
    }
    defer fd.writeUnlock()
    ...

它使用内部同步。除非您正在编写火星着陆器,否则我认为可以假设写入是线程安全的。


推荐阅读