Metered concurrency: Difference between revisions

Content deleted Content added
Sonia (talk | contribs)
→‎Go, Buffered channel: small improvement to code, more explanation.
Sonia (talk | contribs)
Line 606: Line 606:
=={{header|Go}}==
=={{header|Go}}==
===Buffered channel===
===Buffered channel===
Recommended solution for simplicity. Acquire operation is channel send, release is channel receive, and count is provided with len(channel).
Recommended solution for simplicity. Acquire operation is channel send, release is channel receive, and count is provided with cap and len.


To demonstrate, this example implements the [https://en.wikipedia.org/wiki/Semaphore_(programming)#Library_analogy Library analogy] from Wikipedia with 10 study rooms and 20 students.
To demonstrate, this example implements the [https://en.wikipedia.org/wiki/Semaphore_(programming)#Library_analogy Library analogy] from Wikipedia with 10 study rooms and 20 students.
Line 621: Line 621:
"time"
"time"
)
)

// counting semaphore implemented with a buffered channel
type sem chan struct{}

func (s sem) acquire() { s <- struct{}{} }
func (s sem) release() { <-s }
func (s sem) count() int { return cap(s) - len(s) }


// log package serializes output
// log package serializes output
Line 630: Line 637:


func main() {
func main() {
rooms := make(sem, nRooms)
// buffered channel used as a counting semaphore
rooms := make(chan struct{}, nRooms)
for i := 0; i < nRooms; i++ {
rooms <- struct{}{}
}
// WaitGroup used to wait for all students to have studied
// WaitGroup used to wait for all students to have studied
// before terminating program
// before terminating program
Line 646: Line 649:
}
}


func student(rooms chan struct{}, studied *sync.WaitGroup) {
func student(rooms sem, studied *sync.WaitGroup) {
<-rooms // acquire operation
rooms.acquire()
// report per task descrption. also exercise count operation
// report per task descrption. also exercise count operation
fmt.Printf("Room entered. Count is %d. Studying...\n",
fmt.Printf("Room entered. Count is %d. Studying...\n",
len(rooms)) // len function provides count operation
rooms.count())
time.Sleep(2 * time.Second) // sleep per task description
time.Sleep(2 * time.Second) // sleep per task description
rooms <- struct{}{} // release operation
rooms.release()
studied.Done() // signal that student is done
studied.Done() // signal that student is done
}</lang>
}</lang>
Output for this and the other Go programs here shows 10 students studying immediately, about a 2 second pause, 10 more students studying, then another pause of about 2 seconds before returning to the command prompt. In this example the count values may look jumbled. This is a result of the student goroutines running concurrently.
Output for this and the other Go programs here shows 10 students studying immediately, about a 2 second pause, 10 more students studying, then another pause of about 2 seconds before returning to the command prompt. In this example the count values may look jumbled. This is a result of the student goroutines running concurrently.