multiplex_server2.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package main
  5. import "fmt"
  6. type Request struct {
  7. a, b int
  8. replyc chan int // reply channel inside the Request
  9. }
  10. type binOp func(a, b int) int
  11. func run(op binOp, req *Request) {
  12. req.replyc <- op(req.a, req.b)
  13. }
  14. func server(op binOp, service chan *Request, quit chan bool) {
  15. for {
  16. select {
  17. case req := <-service:
  18. go run(op, req)
  19. case <-quit:
  20. return
  21. }
  22. }
  23. }
  24. func startServer(op binOp) (service chan *Request, quit chan bool) {
  25. service = make(chan *Request)
  26. quit = make(chan bool)
  27. go server(op, service, quit)
  28. return service, quit
  29. }
  30. func main() {
  31. adder, quit := startServer(func(a, b int) int { return a + b })
  32. const N = 100
  33. var reqs [N]Request
  34. for i := 0; i < N; i++ {
  35. req := &reqs[i]
  36. req.a = i
  37. req.b = i + N
  38. req.replyc = make(chan int)
  39. adder <- req
  40. }
  41. // checks:
  42. for i := N - 1; i >= 0; i-- { // doesn't matter what order
  43. if <-reqs[i].replyc != N+2*i {
  44. fmt.Println("fail at", i)
  45. } else {
  46. fmt.Println("Request ", i, " is ok!")
  47. }
  48. }
  49. quit <- true
  50. fmt.Println("done")
  51. }