go - 为什么互斥代码会停止另一个完整的 go-routine?

标签 go mutex

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 \n", tag, tag, i)
    time.Sleep(100 * time.Millisecond)
    fmt.Printf("[%s][%s%d]write end \n", tag, tag, i)
    m.Unlock()

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

控制台结果:

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

问题是: 为什么“[WA]”的 go-routine 没有机会? 为什么互斥代码会停止另一个完整的 go-routine?

我知道一定有关于它的故事或理论。 请给我一个网址,以便阅读和学习。

最佳答案

Go 使用协作式多任务处理;它不使用抢占式多任务处理:Computer multitasking .您需要给调度程序一个在锁之间运行的机会。例如,通过调用 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 \n", tag, tag, i)
    time.Sleep(100 * time.Millisecond)
    fmt.Printf("[%s][%s%d]write end \n", tag, tag, i)
    m.Unlock()
    runtime.Gosched()
}

输出:

[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 

关于go - 为什么互斥代码会停止另一个完整的 go-routine?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35932194/

相关文章:

go - 试图在 golang 中获取具有截止日期的锁?

c - try 锁的源代码是什么?

c++ - pthread 互斥锁定和解锁每个变量

go - 打开新的控制台窗口

golang,使用结构作为函数的参数

mongodb - 如何确保 goroutine 在退出前完全运行

go - 将不同的结构传递给函数(GO)?

go - GO语言中slice,channel,map的赋值和直接赋值有什么区别

c++ - 一个互斥锁与多个互斥锁。线程池用哪个好?

c++ - 在 scoped_lock 上进行额外的解锁调用