func Routine1() {
mutex1.Lock()
do something
mutex2.Lock()
mutex3.Lock()
send int to routine 2
send int to routine 3
* Print Something *
mutex2.Unlock()
mutex3.Unlock()
receive ints
do something
mutex2.Lock()
mutex3.Lock()
send int to routine 2
send int to routine 3
Print Something
mutex2.Unlock()
mutex3.Unlock()
do something
receive ints
mutex1.Unlock()
wg.Done()
}
func Routine2() {
mutex2.Lock()
do something
mutex1.Lock()
mutex3.Lock()
send int to routine 1
send int to routine 3
Print Something
mutex1.Unlock()
mutex3.Unlock()
do something
receive ints
mutex1.Lock()
mutex3.Lock()
send int to routine 1
send int to routine 3
Print Something
mutex1.Unlock()
mutex3.Unlock()
do something
receive ints
mutex2.Unlock()
wg.Done()
}
func Routine3() {
// same structure as routine 1 & 2
}
func main() {
wg.Add(3)
go Routine1()
go Routine2()
Routine3()
wg.Wait()
}
This logical code gives deadlock situation every time. Actually, when
it runs, just execute print statement of routine 1 (statement between
* marks) manytimes (though my print statement is only one) and gives
deadlock error. Can anybody inform me what is wrong with the code
logic. Thanks.
NB. For more info, code can be found here, http://play.golang.org/p/pW6aXryUaK,
where only line number 290 is executing. The original code which
contains no error, can be found here play.golang.org/p/UL3rj8DJRk. I
just add lock and unlock to them. Thanks.
I want to add another point: in the code of play.golang.org/p/
UL3rj8DJRk, you can find outputs of various print statements like
this: process [number] sends [int] to process [number] at [time nano
seconds]. However, as the result of three concurrent routines,
sometimes the print statement is not executing properly (means not
printing whole, there is some thing inserted by another print like
process [number] sends [int] to process [number] at process [number]).
Can any body help me how to manage this ?
I do not understand the purpose of why you are using locks like this.
What are those locks supposed to be protecting?
You are quite correct but for even if simple example I can not find
the proper solution how to implement this. For example,
http://play.golang.org/p/jJDY8LFkKu this code. Here I want to put two
prints and sending event inside mutex (for routine 1) thus routine 2
can't interrupt it. Possible solution found is,
http://play.golang.org/p/-uoQSqBJKS. However, it gives deadlock error.
Can you help me how to solve http://play.golang.org/p/-uoQSqBJKS code
problem.
If goroutines lock several mutexes at a time, then they need to lock
them in a consistent order. For example, never lock mutex2 before
mutex1, and never lock mutex3 before mutex2 and mutex1. The rule will
force you to either extend critical sections to the whole goroutines
or use a single mutex.