Mutex: Difference between revisions
→{{header|Go}}: added channel version
(→{{header|Go}}: added channel version) |
|||
Line 263:
=={{header|Go}}==
===sync.Mutex===
{{trans|E}}
<lang go>package main
Line 298 ⟶ 299:
</pre>
Read-write mutex is provided by the <tt>sync.RWMutex</tt> type. For a code example using a RWMutex, see [http://rosettacode.org/wiki/Atomic_updates#RWMutex Atomic updates].
===Channels===
If a mutex is exactly what you need, sync.Mutex is there. As soon as things start getting complicated though, Go channels offer a much clearer alternative. As a gateway from mutexes to channels, here is the above program implemented with channels:
<lang go>package main
import (
"fmt"
"time"
)
var value int
func slowInc(ch, done chan bool) {
// channel receive, used here to implement mutex lock.
// it will block until a value is available on the channel
<-ch
// same as above
v := value
time.Sleep(1e8)
value = v + 1
// channel send, equivalent to mutex unlock.
// makes a value available on channel
ch <- true
// channels can be used to signal completion too
done <- true
}
func main() {
ch := make(chan bool, 1) // ch used as a mutex
done := make(chan bool) // another channel used to signal completion
go slowInc(ch, done)
go slowInc(ch, done)
// a freshly created sync.Mutex starts out unlocked, but a freshly created
// channel is empty, which for us represents "locked." sending a value on
// the channel puts the value up for grabs, thus representing "unlocked."
ch <- true
<-done
<-done
fmt.Println(value)
}</lang>
The value passed on the channel is not accessed here, just as the internal state of a mutex is not accessed. Rather, it is only the effect of the value being available that is important. (Of course if you wanted to send something meaningful on the channel, a reference to the shared resource would be a good start...)
==Icon and {{header|Unicon}}==
|