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
mainreturns
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 providedsync.Cond, condition variable (no barging protection, use infor ! pred()loop)sync.Once, singleton initializationsync.WaitGroup, countdown latch (like a reusable barrier)sync/atomic, CAS, load, store, add on primitive ints and pointers