douci2022 2016-03-11 04:23
浏览 29
已采纳

为什么互斥代码停止另一个完整的例程?

var m *sync.RWMutex
func main() {
    m = new(sync.RWMutex)
    n := 100
    go func() {
        for i := 0; i < n; i++ {
            write("WA", i)
        }
    }()

    go func() {
        for i := 0; i < n; i++ {
            write("WB", i)
        }
    }()

    select {}
}
func write(tag string, i int) {
    m.Lock()
    fmt.Printf("[%s][%s%d]write start 
", tag, tag, i)
    time.Sleep(100 * time.Millisecond)
    fmt.Printf("[%s][%s%d]write end 
", tag, tag, i)
    m.Unlock()

    // time.Sleep(1 * time.Millisecond)
}

Result in console:

go run mutex.go
[WB][WB0]write start
[WB][WB0]write end
[WB][WB1]write start
[WB][WB1]write end
[WB][WB2]write start
[WB][WB2]write end
[WB][WB3]write start
[WB][WB3]write end
[WB][WB4]write start
[WB][WB4]write end
[WB][WB5]write start
[WB][WB5]write end
[WB][WB6]write start
[WB][WB6]write end
[WB][WB7]write start
[WB][WB7]write end
[WB][WB8]write start
[WB][WB8]write end
[WB][WB9]write start
[WB][WB9]write end ...

> go version
go version go1.5.2 windows/amd64

The question is: why there is no chance for the go-routine of "[WA]"? Why the mutex code stops another whole go-routine?

I know there must be a story or a theory about it. Please give me a url to read and study.

  • 写回答

3条回答 默认 最新

  • drau67562 2016-03-11 05:22
    关注

    Go uses cooperative multitasking; it doesn't use preemptive mutitasking: Computer multitasking. You need to give the scheduler an opportunity to run between locks. For example, by a call to Gosched(),

    package main
    
    import (
        "fmt"
        "runtime"
        "sync"
        "time"
    )
    
    var m *sync.RWMutex
    
    func main() {
        m = new(sync.RWMutex)
        n := 100
        go func() {
            for i := 0; i < n; i++ {
                write("WA", i)
            }
        }()
    
        go func() {
            for i := 0; i < n; i++ {
                write("WB", i)
            }
        }()
    
        select {}
    }
    
    func write(tag string, i int) {
        m.Lock()
        fmt.Printf("[%s][%s%d]write start 
    ", tag, tag, i)
        time.Sleep(100 * time.Millisecond)
        fmt.Printf("[%s][%s%d]write end 
    ", tag, tag, i)
        m.Unlock()
        runtime.Gosched()
    }
    

    Output:

    [WB][WB0]write start 
    [WB][WB0]write end 
    [WA][WA0]write start 
    [WA][WA0]write end 
    [WB][WB1]write start 
    [WB][WB1]write end 
    [WA][WA1]write start 
    [WA][WA1]write end 
    [WB][WB2]write start 
    [WB][WB2]write end 
    [WA][WA2]write start 
    [WA][WA2]write end 
    [WB][WB3]write start 
    [WB][WB3]write end 
    [WA][WA3]write start 
    [WA][WA3]write end 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料