Giter Club home page Giter Club logo

semaphore's People

Contributors

robryk avatar

Stargazers

Sal Sal avatar  avatar Carlos R. avatar pmjtoca avatar Simon Menke avatar Adnaan Badr avatar anil avatar

Watchers

James Cloos avatar  avatar pmjtoca avatar  avatar

Forkers

patricktoca

semaphore's Issues

Answer to my previous question. The correct version here.

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)
}

}

A question more than an issue, is my example correct?

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.