Go语言资源自动回收技术
Go语言作为一个现代化的编程语言以及支持垃圾内存的自动回收特性(GC). 我们现在关注的是非内存资源的自动回收技术. 局部资源的管理在讨论Go语言解决方案之前,我们先看看C++是怎么管理资源的. C++中可以可以自动执行的代码主要是构造函数和析构函数. 因此,很多资源的管理技术都是基于构造函数和析构函数实现. 比较常见的是C++的RAII(Resource Acquisition Is Initialization)技术,即初始化中获取资源. 比如在多线程编程中用到的 struct MutexLock { Mutex *const mu_; MutexLock(Mutex *mu): mu_(mu) { mu_->Lock(); } ~MutexLock() { mu_->Unlock(); } }; 这样在使用 void* safeRead(Mutex *mu) { MutexLock locker(mu); if(...) { return NULL; } return read(); } 其实RAII中最重要的是退出 C++的构造函数其实是次要的. 关于禁用C++构造函数的讨论可以参考我的 另一个文章: C++去掉构造函数会怎么样? 因为构造函数经常是通过显示定义变量而隐式调用的,因此用普通的全局函数也 可以实现构造函数的功能(唯一的约束是值容器). 其实C语言的 而作为C语言简约哲学继承者的Go语言同样也没有对构造函数做特殊处理. 在Go语言中构造函数这是约定以 Go语言/UNIX之父 因此,在释放局部资源时,可以用 比如,Go语言版本基于 func safeRead(Mutex *mu) []byte { mu.Lock() defer mu.Unlock() return read(); } 对于可能申请失败的资源也很好处理: func loadFile(name string) ([]byte,error) { f,err := os.Open(name) if err != nil { return nil,err } defer f.Close() return load(f) } 使用 非局部资源的管理我们之前看到的都是在局部使用和释放资源. 如果资源的生命周期很长,而且可能被多个模块共享和随意传递的话, 解决的思路和C++的RAII的方式类似: 我们需要一个能够自己定义的类似 析构函数的技术. 但是因为Go语言有GC特性,因此没有析构函数的概念. 不过 比如,我们可以包装一个文件对象,在没有人使用的时候能够自动关闭: type MyFile struct { f *os.File } func NewFile(name string) (*MyFile,err } runtime.SetFinalizer(f,f.Close) return &MyFile{f:f},nil } func (f *MyFile) Close() { f.f.Close() } 在使用 总结Go语言是短小精悍的语言,它的设计哲学来自UNIX和C语言的KISS原则. 但是Go语言的语法规范虽然很少(50+页),但是却提供了无限可能的组合方式. Go语言之父 参考下数学公理就明白了: 数学的基础规则是很简单的,但是组合方式却是无穷的. Go语言的思路也是提供虽然少但却是正交的基础特性,通过不同特性的无穷的 组合方式来应对各种问题(一个反例就是C++的构造函数和析构函数). 这里我们主要是基于Go语言的 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |