go语言中的互斥 + defer
来源:互联网 发布:怎么在淘宝买电棒 编辑:程序博客网 时间:2024/06/05 17:37
互斥
互斥是传统的并发程序对共享资源进行访问控制的主要手段。它由标准库代码包sync中的Mutex结构体类型代表。sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开方法——Lock和Unlock。顾名思义,前者被用于锁定当前的互斥量,而后者则被用来对当前的互斥量进行解锁。
- 包导入
import "sync" //处理同步需求,导入包
- 定义
我们只需对它进行简单声明就可以正常使用了,就像这样:
var mutex = &sync.RWMutex{} //互斥定义
- 使用
mutex.Lock() // 上锁defer mutex.Unlock() // 解锁,在defer后指定的函数会在函数退出前调用。
- 比如在fabric v0.6 membersrvc/ca/ca.go中的代码片段:
// 通过证书hash值读取证书func (ca *CA) readCertificateByHash(hash []byte) ([]byte, error) { caLogger.Debug("Reading certificate for hash " + string(hash) + ".") mutex.RLock() defer mutex.RUnlock() var raw []byte row := ca.db.QueryRow("SELECT cert FROM Certificates WHERE hash=?", hash) err := row.Scan(&raw) // scan将row中匹配的条目复制到raw指向的值。 return raw, err}
defer
在函数块中使用defer,相当于函数对应的栈空间,先进后出。函数结束后调用栈,进行defer操作。
golang的defer关键字,它可以在函数返回前执行一些操作,最常用的就是打开一个资源(例如一个文件、数据库连接等)时就用defer延迟关闭改资源,以免引起内存泄漏。
如下代码所示,我们一般写打开一个资源是这样操作的:
func ReadWrite() bool { file.Open("file") // to do something if failureX { file.Close() return false } if failureY { file.Close() return false } file.Close() return true}
上面的代码有很多是重复的,go的defer有效解决了这个问题。使用它后,不但代码量减少了很多,而且程序变得更优雅:
func ReadWrite() bool { file.Open("file") defer file.Close() // to do something if failureX { return false } if failureY { return false } return true}
示例代码:
- 代码地址:https://github.com/Agzs/goTest/blob/master/deferTest.go
package mainimport "fmt"import "time"type User struct { username string}func (this *User) Close() { fmt.Println("\n", this.username, "Closed !!!")}func print(z int) { fmt.Println("print z = ", z)}func deferRet(x,y int) (int){ z := 0 defer print(z) // defer后面只能跟函数??? z = x + y fmt.Println("deferRet z = ", z) return z + 50 }func main() { fmt.Println("print name:") u1 := &User{"jack"} defer u1.Close() u2 := &User{"lily"} defer u2.Close() time.Sleep(10 * time.Second) // 实际上,线程Sleep的10秒,u1,和u2早就可以Close()了,但却需要依赖main()函数的结束,才能defer执行。 fmt.Println("main Done !") // 函数中的defer res := deferRet(1,1) fmt.Println("main res = ", res) // 我们可以在官方的文档中看到defer的执行顺序是逆序的,也就是先进后出的顺序: // 打印结果是:4,3,2,1,0 fmt.Printf("print i:") for i := 0; i < 5; i++ { defer fmt.Printf("%d ", i) } fmt.Println("")}
运行程序$ go run deferTest.go
,运行结果:
print name: // 之后光标大概会闪烁10s,然后打印其他信息main Done !deferRet z = 2print z = 0main res = 52print i:4 3 2 1 0 lily Closed !!! jack Closed !!!
参考文章:
http://blog.csdn.net/eclipser1987/article/details/12089271
http://www.jb51.net/article/57335.htm
阅读全文
0 0
- go语言中的互斥 + defer
- Go语言中的defer关键字
- go语言defer使用
- go语言defer使用
- go语言defer使用 .
- Go语言之defer
- Go语言defer
- go语言-defer关键字
- go语言中的defer、panic、recover处理异常
- go语言中的defer、panic、recover处理异常
- Go语言defer的使用
- go语言 golang defer 关注点
- go语言defer的用法
- Go语言defer学习小结
- GO语言defer延迟代码
- Go 语言的分布式读写互斥
- 关于Go语言中defer关键字
- go语言, defer con.Close() 使用之一
- C++将析构函数定义成virtual的原因
- GPIO
- javascript权威指南--第七章
- CRC校验笔记
- Caused by: org.springframework.beans.factory.BeanCreationException
- go语言中的互斥 + defer
- js继承方法的总结
- php stdClass Object转array array解析
- PHP cgi fastcgi & php-fpm 的关系以及理解
- 如何用70行Java代码实现深度神经网络算法
- Codeforces
- CISP国家注册信息安全专员
- ACM省赛海岛争霸(Dijkstra和DFS两种方法)
- TCP窗口控制、流控制、拥塞控制