robryk / semaphore Goto Github PK
View Code? Open in Web Editor NEWA golang implementation of a semaphore.
License: BSD 2-Clause "Simplified" License
A golang implementation of a semaphore.
License: BSD 2-Clause "Simplified" License
countingSemaphore example (corrected version - #should close issue #1):
package main
import (
"fmt"
"time"
"github.com/robryk/semaphore"
)
var (
// max number of goroutines launched concurrently
MaxOutstanding int = 4
// a list to process
list = []int{}
)
func main() {
for i := 1; i <= 10; i++ {
list = append(list, i)
}
Serve(list)
}
// A throttle limiting the number of goroutines started concurrently
// Comment the line with 's.Release(1) and observe the result.
//
func Serve(queue []int) {
// the initial state of s the semaphore is defining the maximum
// goroutines to be started concurrently: the throttle.
//
s := semaphore.New(MaxOutstanding)
msg := make(chan string)
// start n goroutines until the s.Acquire() blocks
//
for i, item := range queue {
go func(i, item int) {
// will not block as long s > 0,
// will be released when another goroutine terminates
s.Acquire(1)
// any processing here
text := fmt.Sprintf("from goroutine[%d]= %d\n", i, item)
msg <- text
// When done; enable another goroutine to run, increase s.
s.Release(1)
}(i, item)
}
for x := 0; x < len(list); x++ {
fmt.Printf(<-msg)
}
}
Hi.
Studying your semaphore implementation I have written this example.
I am wondering if it is compliant with your implementation, and if yes, if it is comparable to the D.Vyukov suggested example (effective go reviews). See in the following example:
/*
Counting Semaphore.
Binary Semaphore (Edsger Dijkstra) and Counting Semaphore (Carel S. Scholten)
are 2 variants of the Semaphore scheme.
A good and short (critical) presentation here: (http://bit.ly/1OCBY9t).
The example below, is a study of the "effective go" example of a channel used as
a semaphore (see https://golang.org/doc/effective_go.html#channels):
func Serve(queue chan *Request) {
for req := range queue {
sem <- 1 // Wait for active queue to drain the buffer of chan sem.
go func(req *Request) {
process(req)
<-sem // Done; enable next request to run.
}(req)
}
}
An alternative solution, was proposed by D.Vyukov:
It initiates a fixed number of Signals (sem <- 1), that limit the number of
started goroutines by construction.
func Serve(queue chan *Request) {
sem := make(chan int, MaxOutstanding)
for i := 0; i < MaxOutstanding; i++ {
sem <- 1
}
for req := range queue {
// acquisition of the semaphore must be on a channel receive, not a send.
//
<-sem
go func() {
process(req)
sem <- 1
}
}
}
In our example, this second approach is implemented using a Counting Semaphore.
See in the code below: Acquire(n) and Release(1) n times.
To be note: we are using the robust Semaphore implementation by R.Obryk,
available here: github.com/robryk/semaphore.
*/
package main
import (
"fmt"
"github.com/semaphore"
)
var (
// max number of goroutines launched concurrently
MaxOutstanding int = 4
// a list to process
list = []int{}
)
func main() {
for i:=1; i<=10; i++ {
list = append(list, i)
}
Serve(list)
}
// Observe the difference with the 1st Effective Go example (in comment above).
// In case of overload, a 'Wait' is organized limiting the number of concurrent
// goroutines: a go throttle.
//
func Serve(queue []int) {
s := semaphore.NewSemaphore(MaxOutstanding)
msg := make(chan string)
// Wait for goroutines to drain the 'counting semaphore',
// when drained: blocks until a 'next release'!
s.Acquire(MaxOutstanding)
// start n goroutines until the s.Acquire() blocks
for i, item := range queue {
go func(i, item int) {
// any processing here
text := fmt.Sprintf("from goroutine[%d]= %d\n", i, item)
msg <- text
// Done; enable next task to run (drain the counting semaphore of 1).
s.Release(1)
}(i, item)
}
for x:=0; x < len(list); x++ {
fmt.Printf(<-msg)
}
}
Thanks in advance for your feed-back.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.