如果没有互斥锁,并行处理切片将无法正常工作

时间:2017-05-05 08:00:01

标签: go concurrency

函数WithMutexWithoutMutex会产生不同的结果。

即使我已设置WithoutMutex

Waitgroup实施也会失去价值。

可能出现什么问题?

Do not run on Playground

P.S。我在Windows 10和Go 1.8.1上

package main

import (
    "fmt"
    "sync"
)

var p = fmt.Println

type MuType struct {
    list []int
    *sync.RWMutex
}

var muData *MuType
var data *NonMuType

type NonMuType struct {
    list []int
}

func (data *MuType) add(i int, wg *sync.WaitGroup) {
    data.Lock()
    defer data.Unlock()
    data.list = append(data.list, i)
    wg.Done()

}

func (data *MuType) read() []int {
    data.RLock()
    defer data.RUnlock()
    return data.list
}

func (nonmu *NonMuType) add(i int, wg *sync.WaitGroup) {
    nonmu.list = append(nonmu.list, i)
    wg.Done()

}

func (nonmu *NonMuType) read() []int {
    return nonmu.list
}

func WithoutMutex() {
    nonmu := &NonMuType{}
    nonmu.list = make([]int, 0)
    var wg = sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go nonmu.add(i, &wg)

    }
    wg.Wait()
    data = nonmu
    p(data.read())
}

func WithMutex() {
    mtx := &sync.RWMutex{}
    withMu := &MuType{list: make([]int, 0)}
    withMu.RWMutex = mtx
    var wg = sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go withMu.add(i, &wg)
    }
    wg.Wait()
    muData = withMu
    p(muData.read())
}

func stressTestWOMU(max int) {
    p("Without Mutex")
    for ii := 0; ii < max; ii++ {
        WithoutMutex()
    }
}

func stressTest(max int) {
    p("With Mutex")
    for ii := 0; ii < max; ii++ {
        WithMutex()
    }
}

func main() {
    stressTestWOMU(20)
    stressTest(20)
}

1 个答案:

答案 0 :(得分:1)

对于并发写入来说,切片是不安全的,所以我并不感到惊讶WithoutMutex看起来根本不一致,并且丢弃了项目。

WithMutex版本始终有10个项目,但是订单混乱。这也是预料之中的,因为互斥锁可以保护它,因此一次只能添加一个互斥锁。虽然不知道哪个goroutine会按哪种顺序运行,但是看看哪个快速生成的goroutine会首先追加它是一场竞赛。

waitgroup不会执行任何操作来控制访问或强制执行排序。它只是在最后提供了一切信号。