在一块结构中转到锁定

时间:2018-05-05 05:56:39

标签: go parallel-processing goroutine locks

我是GO的新手。我特意尝试使用锁定并行地向数组添加值(我不想使用通道)。但不知何故,我的答案是不正确的。我尝试了两种方法。将指针传递给切片并传递切片本身。我不是在寻找全局锁定变量。

方法1(传递指针)

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);
}

方法2(传递切片)

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);
}

在任何一种情况下输出都不正确。

1 个答案:

答案 0 :(得分:1)

您似乎正在正确使用锁定,但不会等待goroutines来完成&#34;完成&#34;在打印arr之前。尝试添加一个小<-time.After(time.Second),或使用WaitGroup,或使用select等待所有goroutine完成,或将fmt.Println(ar[i].population)放在goroutines中以查看您想要查看的结果!< / p>

如果您只是在没有等待它们完成的情况下启动一堆goroutine,就会发生同样的事情。

以下是一个完整的工作示例,其中包含额外的ID&#39;为了清楚起见,每个goroutine。请注意,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)
}