go同步编程

栏目: Go · 发布时间: 6年前

内容简介:函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。对于同一个读写锁来说,施加在它之上的读锁定可以有多个。因此,只有我们对互斥锁进行相同数量的读解锁,才能够让某一个相应的写锁定获得进行的机会。*sync.RWMutex类型都没有相应的方法让我们获得已进行的读锁定的数量,所以这里是很容易出现问题的。还好我们可以使用defer语句来尽量避免此类问题的发生。

互斥锁

函数write中的这条defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。

var mutex sync.Mutex
func write() {
mutex.Lock()
defer mutex.Unlock()
// 省略若干条语句
}
func repeatedlyLock() {
    var mutex sync.Mutex
    fmt.Println("Lock the lock. (G0)")
    mutex.Lock()
    fmt.Println("The lock is locked. (G0)")
    for i := 1; i <= 3; i++ {
        //开启3个协程,mutex已经锁定,所以程序会被阻塞。在unlock之后,随机启动一个。
        go func(i int) {
            //协程阻塞,只打印这一行。
            fmt.Printf("Lock the lock. (G%d)\n", i)
            mutex.Lock()
            fmt.Printf("The lock is locked. (G%d)\n", i)
        }(i)
    }

    time.Sleep(time.Second)
    fmt.Println("Unlock the lock. (G0)")
    mutex.Unlock()
    fmt.Println("The lock is unlocked. (G0)")
    time.Sleep(time.Second)
}

虽然互斥锁可以被直接的在多个Goroutine之间共享,但是我们还是强烈建议把对同一个互斥锁的成对的锁定和解锁操作放在同一个层次的代码块中。例如,在同一个函数或方法中对某个互斥锁的进行锁定和解锁。又例如,把互斥锁作为某一个结构体类型中的字段,以便在该类型的多个方法中使用它。

读写锁

  • 多个写操作之间都是互斥的.
  • 写操作与读操作之间也都是互斥的.
  • 多个读操作之间却不存在互斥关系.
func (*RWMutex) Lock //写锁定
func (*RWMutex) Unlock //写解锁
func (*RWMutex) RLock //读锁定
func (*RWMutex) RUnlock //读解锁

对于同一个读写锁来说,施加在它之上的读锁定可以有多个。因此,只有我们对互斥锁进行相同数量的读解锁,才能够让某一个相应的写锁定获得进行的机会。*sync.RWMutex类型都没有相应的方法让我们获得已进行的读锁定的数量,所以这里是很容易出现问题的。还好我们可以使用defer语句来尽量避免此类问题的发生。

package main
import (
    "sync"
    "time"
)

var m *sync.RWMutex
func main() {
    m = new(sync.RWMutex)
    //可以多个同时读
    go read(1)
    go read(2)
    time.Sleep(2 * time.Second)
}
func read(i int) {
    println(i, "read start")
    m.RLock()
    println(i, "reading")
    time.Sleep(1 * time.Second)
    m.RUnlock()
    println(i, "read end")
}
package main
import (
    "sync"
    "time"
)
var m *sync.RWMutex
func main() {
    m = new(sync.RWMutex)
    //写的时候啥都不能干
    go write(1)
    go read(2)
    go write(3)
    time.Sleep(4 * time.Second)
}
func read(i int) {
    println(i, "read start")
    m.RLock()
    println(i, "reading")
    time.Sleep(1 * time.Second)
    m.RUnlock()
    println(i, "read end")
}
//1 write end结束之后,2才能reading
//2 read end结束之后,3 才能writing
func write(i int) {
    println(i, "write start")
    m.Lock()
    println(i, "writing")
    time.Sleep(1 * time.Second)
    m.Unlock()
    println(i, "write end")
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

第二次机器革命

第二次机器革命

[美]埃里克·布莱恩约弗森 / 蒋永军 / 中信出版社 / 2014-9 / 59.80

“一本非常鼓舞人心的书!”——托马斯•L•弗里德曼 《世界是平的》作者 一场革命开始了! 在《第二次机器革命》这本书中,埃里克•布莱恩约弗森和安德鲁•麦卡菲——这两位处于数字技术时代最前沿的思想家,向我们阐述了驱动我们经济和生活的发生变革的力量。他们认为,数字技术将会给我们带来难以想象的巨大变革:想象一下令人眩目的个人数字技术产品、一流的基础设施,都将会给我们带来极大的便利。数字技术(......一起来看看 《第二次机器革命》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具