dte29947 2017-05-05 08:00
浏览 42
已采纳

没有互斥锁,并发处理切片无法按预期工作

Functions WithMutex and WithoutMutex are giving different results.

WithoutMutex implementation is losing values even though I have Waitgroup set up.

What could be wrong?

Do not run on Playground

P.S. I am on Windows 10 and 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条回答 默认 最新

  • dongtang1997 2017-05-05 08:07
    关注

    Slices are not safe for concurrent writes, so I am in no way surprised that WithoutMutex does not appear to be consistent at all, and has dropped items.

    The WithMutex version consistently has 10 items, but in jumbled orders. This is also to be expected, since the mutex protects it so that only one can append at a time. There is no guarantee as to which goroutine will run in which order though, so it is a race to see which of the rapidly spawned goroutines will get to append first.

    The waitgroup does not do anything to control access or enforce ordering. It merely provides a signal at the end that everything is done.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 高维数据处理方法求指导
  • ¥100 数字取证课程 关于FAT文件系统的操作
  • ¥15 如何使用js实现打印时每页设置统一的标题
  • ¥15 安装TIA PortalV15.1报错
  • ¥15 能把水桶搬到饮水机的机械设计
  • ¥15 Android Studio中如何把H5逻辑放在Assets 文件夹中以实现将h5代码打包为apk
  • ¥15 使用小程序wx.createWebAudioContext()开发节拍器
  • ¥15 关于#爬虫#的问题:请问HMDB代谢物爬虫的那个工具可以提供一下吗
  • ¥15 vue3+electron打包获取本地视频属性,文件夹里面有ffprobe.exe 文件还会报错这是什么原因呢?
  • ¥20 用51单片机控制急停。