GO语言学习笔记-互斥锁
原文,互斥锁(Mutex)也是go并发系列最后一篇文章。
临界区
在说互斥锁前,理解并发编程中的临界区(Critical section)是十分重要的。当一个程序并发执行时,共享资源不应该在同一时刻被多个goroutine修改。这段修改共享资源的代码就叫做临界区。举个例子,我们有一个代码片段用于修改变量x自增1。
x = x+1
如果上面的代码在唯一的goroutine中执行,不会有任何问题。
原文,互斥锁(Mutex)也是go并发系列最后一篇文章。
在说互斥锁前,理解并发编程中的临界区(Critical section)是十分重要的。当一个程序并发执行时,共享资源不应该在同一时刻被多个goroutine修改。这段修改共享资源的代码就叫做临界区。举个例子,我们有一个代码片段用于修改变量x自增1。
x = x+1
如果上面的代码在唯一的goroutine中执行,不会有任何问题。
select
语法用来从多个读/写的channel中选择一个,如果没有任何channel就绪select语句将被阻塞。如果多个就绪,则随机选择一个。语法和switch
类似,除了case后面跟随的是channel。
原文,这里为了方便理解我把worker pools翻译成线程池。
之前讨论的所有channel都是不带缓冲区的,因此读取和写入都会被阻塞。创建一个带缓冲区的channel也是可能的,这种channel只有在缓冲区满后再写入或者读取一个空的channel时才会被阻塞。
创建一个带缓冲区的channel需要一个额外的参数容量来表明缓冲区大小:
ch := make(chan type, capacity)
上面代码中的 capacity 需要大于0,如果等于0的话则是之前学习的无缓冲区channel。
原文,建议先看完goroutine部分再看这篇。
channels可以理解成是goroutine之间通信的管道,和水流从管道的一端到另一端类似,数据也可以从管道的一端发送另一端接收。
原文,建议理解并发(concurrency)、并行(parallelism)区别后再看这方面的内容。
Goroutines是一个可以和其他函数或方法并发执行的函数或方法。也可以把它理解为轻量级的线程(roy注:这话听起来和大python中的协程很像啊!),而创建Goroutine的开销却远远小于线程。因此在大多数的Go程序都可以并发执行成千上万的Goroutine。
上篇文章中所有接口实现我们都使用的传值,当然也可以使用传指针这种方式来实现接口。但使用传指针这种方式有一点需要注意,我们来看下面这个代码。
package main
import "fmt"
type Describer interface {
Describe()
}
type Person struct {
name string
age int
}
func (p Person) Describe() { //implemented using value receiver
fmt.Printf("%s is %d years old\n", p.name, p.age)
}
type Address struct {
state string
country string
}
func (a *Address) Describe() { //implemented using pointer receiver
fmt.Printf("State %s Country %s", a.state, a.country)
}
func main() {
var d1 Describer
p1 := Person{"Sam", 25}
d1 = p1
d1.Describe()
p2 := Person{"James", 32}
d1 = &p2
d1.Describe()
var d2 Describer
a := Address{"Washington", "USA"}
/* compilation error if the following line is
uncommented
cannot use a (type Address) as type Describer
in assignment: Address does not implement
Describer (Describe method has pointer
receiver)
*/
//d2 = a
d2 = &a //This works since Describer interface
//is implemented by Address pointer in line 22
d2.Describe()
}