Metered concurrency: Difference between revisions
Content added Content deleted
No edit summary |
(→Buffered channel: bug fix. previous version worked with existing compiler but was technically invalid.) |
||
Line 414: | Line 414: | ||
Recommended solution for simplicity. Acquire operation is channel send, release is channel receive, and count is provided with len(channel). Also WaitGroup used as a completion checkpoint. |
Recommended solution for simplicity. Acquire operation is channel send, release is channel receive, and count is provided with len(channel). Also WaitGroup used as a completion checkpoint. |
||
<lang go>package main |
<lang go>package main |
||
import ( |
import ( |
||
"log" |
"log" |
||
Line 421: | Line 421: | ||
"time" |
"time" |
||
) |
) |
||
// log package serializes output |
// log package serializes output |
||
var fmt = log.New(os.Stdout, "", 0) |
var fmt = log.New(os.Stdout, "", 0) |
||
// library analogy per WP article |
|||
const nRooms = 10 |
const nRooms = 10 |
||
const nStudents = 20 |
const nStudents = 20 |
||
func main() { |
func main() { |
||
// |
// buffered channel used as a counting semaphore |
||
rooms := make(chan int, nRooms) |
|||
for i := 0; i < nRooms; i++ { |
|||
rooms <- 1 |
|||
} |
|||
⚫ | |||
// before terminating program |
|||
var studied sync.WaitGroup |
var studied sync.WaitGroup |
||
studied.Add(nStudents) |
studied.Add(nStudents) |
||
// nStudents run concurrently |
|||
for i := 0; i < nStudents; i++ { |
for i := 0; i < nStudents; i++ { |
||
go student( |
go student(rooms, &studied) |
||
} |
} |
||
⚫ | |||
studied.Wait() |
studied.Wait() |
||
} |
} |
||
func student( |
func student(rooms chan int, studied *sync.WaitGroup) { |
||
<-rooms // acquire operation |
|||
// 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 |
|||
time.Sleep(2 * time.Second) // sleep per task description |
time.Sleep(2 * time.Second) // sleep per task description |
||
<- |
rooms <- 1 // release operation |
||
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. |
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. |
||
===Sync.Cond=== |
===Sync.Cond=== |
||
A more traditional approach implementing a counting semaphore object with sync.Cond. It has a constructor and methods for the three operations requested by the task. |
A more traditional approach implementing a counting semaphore object with sync.Cond. It has a constructor and methods for the three operations requested by the task. |