Metered concurrency: Difference between revisions
Content deleted Content added
m →{{header|Tcl}}: metadata improvement |
Go solution |
||
Line 328: | Line 328: | ||
work(i, 2000, semaphore, timer, println) |
work(i, 2000, semaphore, timer, println) |
||
}</lang> |
}</lang> |
||
=={{header|Go}}== |
|||
Implementation using Go channels. |
|||
<lang go>package main |
|||
import ( |
|||
"fmt" |
|||
"time" |
|||
) |
|||
func main() { |
|||
// three operations per task description |
|||
acquire := make(chan int) |
|||
release := make(chan int) |
|||
count := make(chan chan int) |
|||
// library analogy per WP article |
|||
go librarian(acquire, release, count, 10) |
|||
nStudents := 20 |
|||
studied := make(chan int) // done channel |
|||
for i := 0; i < nStudents; i++ { |
|||
go student(acquire, release, studied) |
|||
} |
|||
// wait until all students are done |
|||
for i := 0; i < nStudents; i++ { |
|||
<-studied |
|||
} |
|||
} |
|||
func librarian(a, r chan int, c chan chan int, count int) { |
|||
p := a // accquire operation is served or not depending on count |
|||
for { |
|||
select { |
|||
case <-p: // accquire/p/wait operation |
|||
count-- |
|||
if count == 0 { |
|||
p = nil |
|||
} |
|||
case <-r: // release operation |
|||
count++ |
|||
p = a |
|||
case cc := <-c: // count operation |
|||
cc <- count |
|||
} |
|||
} |
|||
} |
|||
func student(a, r, s chan int) { |
|||
a <- 0 // accquire |
|||
fmt.Println("Studying...") // report per task descrption |
|||
time.Sleep(2e9) // sleep per task description |
|||
r <- 0 // release |
|||
s <- 0 // signal done |
|||
}</lang> |
|||
Output 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. |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |