问题
I have two concurrent go routines like below,
Routine 1{
routine procedure
critical section{
}
routine procedure
}
Routine 2{
routine procedure
critical section{
}
routine procedure
}
Is it possible by using some go inbuilt functions to implement critical section ?
回答1:
Your question:
I have N concurrent go routines (all more or less same purpose). Each of those have a critical section. Before entering critical section, each routine just do some message sending job. When it enters critical section, I need all other routines must stop execution until it exits critical section. Is it possible by using any library function in GO?
What you are asking about (to force a stop on all other goroutines while one goroutine is in the critical section) is not typical in Go programs. There is no library function to stop all other goroutines, so you will need to stop them by designing proper synchronization among goroutines in your program. The typical scenario is for all goroutines to (potentially) run concurrently, except for those goroutines that are blocked somehow.
To control concurrent access to a shared resource in a Go program you can use Go channels, the "sync"
package, pipes, or network connections.
Using sync.Mutex
, the Go code may look like this (but please keep in mind that, whenever possible, Go programs should preferably use Go channels instead of mutexes):
package main
import "sync"
var m sync.Mutex
var wg sync.WaitGroup
func routine1() {
... do something ...
m.Lock()
... critical section (access the shared resource here) ...
m.Unlock()
... do something ...
wg.Done()
}
func routine2() {
... do something ...
m.Lock()
... critical section (access the shared resource here) ...
m.Unlock()
... do something ...
wg.Done()
}
func main() {
wg.Add(1); go routine1()
wg.Add(1); go routine2()
wg.Wait()
}
回答2:
You could try using a buffered channel:
c := make(chan int, 2)
This will buffer the data sent before actually sending it.
回答3:
Do you mean something like this?
package main
import "fmt"
func ping(recv <-chan int, send chan<- int, end chan<- bool) {
fmt.Println("ping")
send <- 11
send <- 12
r1 := <-recv
r2 := <-recv
fmt.Println("ping", r1, r2)
end <- true
}
func pong(recv <-chan int, send chan<- int, end chan<- bool) {
fmt.Println("pong")
r1 := <-recv
r2 := <-recv
send <- 21
send <- 22
fmt.Println("pong", r1, r2)
end <- true
}
func main() {
chEnd := make(chan bool)
chPing := make(chan int, 2)
chPong := make(chan int, 2)
go ping(chPing, chPong, chEnd)
go pong(chPong, chPing, chEnd)
<-chEnd
<-chEnd
fmt.Println("end")
}
Output:
ping
pong
pong 11 12
ping 21 22
end
回答4:
I don't think, there is any library in go to implement critical section. I think Arpssss is asking for a library.
回答5:
Several approaches are possible. A simple one is to use channels typed for the full "event".
package main
type int2 struct {
a, b int
}
func Routine1(tx, rx chan int2) {
var x, y int
// ...
tx <- int2{x, y}
// ...
z := <- rx // Two rx values in z.a, z.b
// ...
}
func Routine2(rx, tx chan int2) {
var x, y int
// ...
z := <- rx // Two rx values in z.a, z.b
// ...
tx <- int2{x, y}
// ...
}
func main() {
// ...
tx, rx := make(chan int2), make(chan int2)
go Routine1(tx, rx)
go Routine2(rx, tx)
// ...
}
回答6:
Here's a channel based equivalent to Atom's solution. Do this before starting your goroutines:
doingFileModificationJobs := make(chan bool, 1)
doingFileModificationJobs <- false
and then pass this channel as a parameter when you start goroutines. Note that there is just one channel. All goroutines use this same channel.
This will let you use this channel like a mutex. Replace your pseudocode,
critical section{
with
<-doingFileModicationJobs
and then replace the matching closing brace of your critical section pseudocode with,
doingFileModications <- false
It reads nicely that way and is more descriptive than general terms like "mutex" or "critical section."
This serializes your file modification jobs and ensures that only one goroutine at a time can be be doing them. I think this is the common concept of a critical section, but if you really need other goroutines to stop, even if they are just doing the message sending jobs, well, that's a different problem.
来源:https://stackoverflow.com/questions/8286806/go-programming-language-mutual-concurrent-execution