Go 锁定一片结构
Go Locks in a slice of struct
我是 GO 新手。我专门尝试使用锁将值并行添加到数组(我不想使用通道)。但不知何故,我的回答是不正确的。我已经尝试了这两种方法。将指针传递给切片并传递切片本身。我不是在寻找全局锁变量。
方法一(传递指针)
type locks_block struct {
population int
mux sync.Mutex
}
func incr(ar *[] locks_block){
for i:=0;i<len(*ar);i++ {
(*ar)[i].mux.Lock()
(*ar)[i].population = (*ar)[i].population+1;
(*ar)[i].mux.Unlock()
}
}
func main() {
arr := make([]locks_block,5);
go incr(&arr);
go incr(&arr);
go incr(&arr);
go incr(&arr);
fmt.Println(arr);
}
方法二(传切片)
type locks_block struct {
population int
mux sync.Mutex
}
func incr(ar [] locks_block){
for i:=0;i<len(ar);i++ {
ar[i].mux.Lock()
ar[i].population = ar[i].population+1;
ar[i].mux.Unlock()
}
}
func main() {
arr := make([]locks_block,5);
go incr(arr);
go incr(arr);
go incr(arr);
go incr(arr);
fmt.Println(arr);
}
两种情况下的输出都不正确。
看来您正在正确使用锁,但在打印 arr
之前没有等待 goroutines "finish"。尝试添加一个小 <-time.After(time.Second)
,或使用 WaitGroup,或使用 select
等待所有 goroutines 完成,或将 fmt.Println(ar[i].population)
放在 goroutines 中以查看您想要看到的结果!
如果你只是启动一堆 goroutines 而没有等待它们完成,也会发生同样的事情。
这是一个完整的工作示例,为清楚起见,每个 goroutine 都有一个额外的 'id'。注意goroutines的顺序不一致!
package main
import (
"fmt"
"sync"
"time"
)
type locks_block struct {
population int
mux sync.Mutex
}
func incr(id int, ar []locks_block) {
for i := 0; i < len(ar); i++ {
ar[i].mux.Lock()
ar[i].population = ar[i].population + 1
fmt.Printf("goroutine #%v, population %v\n", id, ar[i].population)
ar[i].mux.Unlock()
}
}
func main() {
arr := make([]locks_block, 5)
go incr(1, arr)
go incr(2, arr)
go incr(3, arr)
go incr(4, arr)
// this should give the goroutines enough time
<-time.After(time.Millisecond * 500)
fmt.Println(arr)
}
我是 GO 新手。我专门尝试使用锁将值并行添加到数组(我不想使用通道)。但不知何故,我的回答是不正确的。我已经尝试了这两种方法。将指针传递给切片并传递切片本身。我不是在寻找全局锁变量。
方法一(传递指针)
type locks_block struct {
population int
mux sync.Mutex
}
func incr(ar *[] locks_block){
for i:=0;i<len(*ar);i++ {
(*ar)[i].mux.Lock()
(*ar)[i].population = (*ar)[i].population+1;
(*ar)[i].mux.Unlock()
}
}
func main() {
arr := make([]locks_block,5);
go incr(&arr);
go incr(&arr);
go incr(&arr);
go incr(&arr);
fmt.Println(arr);
}
方法二(传切片)
type locks_block struct {
population int
mux sync.Mutex
}
func incr(ar [] locks_block){
for i:=0;i<len(ar);i++ {
ar[i].mux.Lock()
ar[i].population = ar[i].population+1;
ar[i].mux.Unlock()
}
}
func main() {
arr := make([]locks_block,5);
go incr(arr);
go incr(arr);
go incr(arr);
go incr(arr);
fmt.Println(arr);
}
两种情况下的输出都不正确。
看来您正在正确使用锁,但在打印 arr
之前没有等待 goroutines "finish"。尝试添加一个小 <-time.After(time.Second)
,或使用 WaitGroup,或使用 select
等待所有 goroutines 完成,或将 fmt.Println(ar[i].population)
放在 goroutines 中以查看您想要看到的结果!
如果你只是启动一堆 goroutines 而没有等待它们完成,也会发生同样的事情。
这是一个完整的工作示例,为清楚起见,每个 goroutine 都有一个额外的 'id'。注意goroutines的顺序不一致!
package main
import (
"fmt"
"sync"
"time"
)
type locks_block struct {
population int
mux sync.Mutex
}
func incr(id int, ar []locks_block) {
for i := 0; i < len(ar); i++ {
ar[i].mux.Lock()
ar[i].population = ar[i].population + 1
fmt.Printf("goroutine #%v, population %v\n", id, ar[i].population)
ar[i].mux.Unlock()
}
}
func main() {
arr := make([]locks_block, 5)
go incr(1, arr)
go incr(2, arr)
go incr(3, arr)
go incr(4, arr)
// this should give the goroutines enough time
<-time.After(time.Millisecond * 500)
fmt.Println(arr)
}