Reputation: 337
I am a newbie in Go, i wrote this code and hope it will enter deadlock status, but failed.
var mux sync.Mutex
func main() {
runtime.GOMAXPROCS(1)
for i := 0; i < 3; i++ {
go func() {
log.Println("Trying to Lock the Mux")
mux.Lock()
log.Println("The mux is Locked")
}()
}
runtime.Gosched()
}
//Output:
//2017/01/17 08:59:42 Trying to Lock the Mux
//2017/01/17 08:59:42 The mux is Locked
//2017/01/17 08:59:42 Trying to Lock the Mux
//2017/01/17 08:59:42 Trying to Lock the Mux
As you can see. this code run well and print something and then quit without any deadlock error. For I know, the first go func(){} goroutine has returned and locked the mux then quit. But the other two goroutines will be blocked because the mux has already blocked.
The function runtime.Gosched() should push the main goroutine to the only FIFO queue(runtime.GOMAXPROCS(1)) right? why it can be excute before the left two goroutine that already in the queue?
BTW,this following code will return the deadlock error as expected
var mux sync.Mutex
func main() {
runtime.GOMAXPROCS(1)
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 3; i++ {
go func() {
defer wg.Done()
log.Println("Trying to Lock the Mux")
mux.Lock()
log.Println("The mux is Locked")
}()
}
wg.Wait()
}
Thanks!
Upvotes: 0
Views: 416
Reputation: 33637
A deadlock is a condition where all the goroutines are in waiting state (waiting for lock or reading from channel etc). The reason is simple, if all of them are waiting then there is no one left that can do something that lead to any of the waiting goroutines to continue. In your case your main function, which is also a goroutine is not in waiting state. When the main goroutine exits the process exits too.
The function runtime.Gosched() should push the main goroutine to the only FIFO queue(runtime.GOMAXPROCS(1)) right? why it can be excute before the left two goroutine that already in the queue?
The queue is a schedule queue. The runtime will pick a goroutine from the queue, run it for some time, pause it, pick another goroutine.
Upvotes: 2
Reputation: 10254
For your code:
var mux sync.Mutex
func main() {
runtime.GOMAXPROCS(1)
for i := 0; i < 3; i++ {
go func() {
log.Println("Trying to Lock the Mux")
mux.Lock()
log.Println("The mux is Locked")
}()
}
runtime.Gosched()
}
There is no deadlock, for
func (m *Mutex) Lock()
Lock locks m. If the lock is already in use, the calling goroutine blocks until the mutex is available.
So the second and third goroutine just wait there. This is busy waiting. then the main goroutine exit, so the second and third goroutine also exist.
Upvotes: 1