Metered concurrency: Difference between revisions
Content deleted Content added
→Go, Buffered channel: small improvement to code, more explanation. |
→Buffered channel: clarity |
||
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 |
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) 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() { |
||
⚫ | |||
// buffered channel used as a counting semaphore |
|||
⚫ | |||
for i := 0; i < nRooms; i++ { |
|||
⚫ | |||
} |
|||
// 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 |
func student(rooms sem, studied *sync.WaitGroup) { |
||
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", |
||
rooms.count()) |
|||
time.Sleep(2 * time.Second) // sleep per task description |
time.Sleep(2 * time.Second) // sleep per task description |
||
rooms |
rooms.release() |
||
studied.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. |