CS343

Go Language

Go is a non-object-oriented systems language with light-weight preemptive threads (goroutines) and channel-based communication in the CSP tradition. The concurrency primitive shift, from routine calls to typed shared buffers, is what makes Go interesting relative to uC++.

Why channels instead of direct calls?

Because goroutines have no identity you can reference, go foo() returns nothing, and there is no return value from the goroutine. Without a callee object you can’t invoke a member on it, so synchronization must happen through a third-party buffer. Channels are that buffer, typed, sized, and send/receive blocks when full/empty.

Resources

Goroutine

go foo( 3, f )          // start thread in foo; return value discarded
  • Light-weight, preemptive, M:N scheduled
  • No way to reference the goroutine object, no direct communication or termination synchronization
  • All goroutines terminate silently when main returns

Channel

A typed shared buffer of 0 to N elements, the only sanctioned synchronization/communication primitive:

ch1 := make( chan int, 100 )     // buffered: up to 100 async sends
ch2 := make( chan string )       // unbuffered: synchronous rendezvous
ch1 <- 1                         // send
x := <-ch1                       // receive
  • Buffer size 0 ⇒ synchronous (matches uC++ _Accept)
  • Buffer size > 0 ⇒ up to N asynchronous sends before blocking
  • Send/receive can be constrained to one direction on a channel type

select, multi-channel rendezvous

Direct analogue of uC++‘s _Accept ... or _Accept ...:

select {
    case i = <-ch1: fmt.Println( i )
    case f = <-ch2: fmt.Println( f )
    case <-hand:    break L            // sentinel
}

Lock library

Since channels are awkward for classical mutual exclusion, Go also ships traditional locks in sync:

  • sync.Mutex, sync.RWMutex, recursive not provided
  • sync.Cond, condition variable (no barging protection, use in for ! pred() loop)
  • sync.Once, singleton initialization
  • sync.WaitGroup, countdown latch (like a reusable barrier)
  • sync/atomic, CAS, load, store, add on primitive ints and pointers