2 回答
TA贡献1828条经验 获得超13个赞
控制并发访问的一种简单方法是通过服务 goroutine,从通道接收消息。该 goroutine 将拥有对该文件的唯一访问权限。因此,访问将是顺序的,没有任何竞争问题。
通道在交错请求方面做得很好。客户端写入通道而不是直接写入文件。频道上的消息会自动为您交错。
与简单地使用互斥锁相比,这种方法的好处在于您可以开始将程序视为微服务的集合。这是 CSP 方式,可以轻松地从较小的组件组合大型系统。
TA贡献1797条经验 获得超4个赞
有很多方法可以控制并发访问。最简单的方法是使用Mutex:
var mu sync.Mutex
func WriteToFile( i int, f *os.File, w *sync.WaitGroup ){
mu.Lock()
defer mu.Unlock()
// etc...
}
至于为什么你没有看到问题,Go 使用操作系统调用来实现文件访问,并且这些系统调用是线程安全的(强调):
根据 POSIX.1-2008/SUSv4 Section XSI 2.9.7(“与常规文件操作的线程交互”):
在 POSIX.1-2008 中指定的效果中,当它们对常规文件或符号链接进行操作时,以下所有函数都应该是原子的: ...
随后列出的 API 包括 write() 和 writev(2)。跨线程(和进程)应该是原子的,其中包括文件偏移的更新。但是,在 3.14 版之前的 Linux 上,情况并非如此:如果共享打开文件描述(请参阅 open(2))的两个进程同时执行 write()(或 writev(2)),则 I /O 操作在更新文件偏移量方面不是原子的,因此两个进程输出的数据块可能(错误地)重叠。 此问题已在 Linux 3.14 中修复。
我仍然会使用锁,因为 Go 代码不是自动线程安全的。(两个 goroutine 修改同一个变量会导致奇怪的行为)
- 2 回答
- 0 关注
- 223 浏览
添加回答
举报