Skip to content

Instantly share code, notes, and snippets.

@JohnMurray
Last active August 16, 2017 07:41
Show Gist options
  • Save JohnMurray/dab6c8bc45c60305589a328fb47a6011 to your computer and use it in GitHub Desktop.
Save JohnMurray/dab6c8bc45c60305589a328fb47a6011 to your computer and use it in GitHub Desktop.
Challenge 1 of go lunch-and-learn

Ping Pong

A big reason people love Go is the concurrency primitives. Let's try them out with a coding challenge.

Goal

Launch 2 go-routines that send messages to each other over a channel. One go-routine will send "Ping" and the other will send "Pong." Each go-routine can only respond after they've received a message from the other go-routine. The exception is that the go-routine sending "Ping" can send an initial message un-prompted.

Cheat Sheet

create a channel

unbuffered_channel = make(chan string)

buffered_channel = make(chan string, 5)

write to channel

muffin_chan = make(chan string, 10)
msg := "muffins"

muffin_chan <- msg
for {
  // will block go-routine if channel buffer is full
  muffin_chan <- "infinite muffins"
}

launch a go-routine w/ a chan

func AsyncPrinter(msg_stream chan string) {
  for {
    msg := <- msg_stream
    fmt.Println(msg)
  }
}

func main() {
  muffin_stream := make(chan string, 100)
  go AsyncPrinter(muffin_stream)

  for {
    muffin_stream <- "MUFFINS!!!"
  }
}

sleep a go-routine for X millis

import (
  "fmt"
  "time"
)

func main() {
  for {
    time.Sleep(100 * time.Millisecond)
    fmt.Println("witness my delay...")
  }
}

"hand off" main thread to go-routines

import (
  "fmt"
  "runtime"
  "time"
)

func IRunForever() {
  for {
    time.Sleep(100)
    fmt.Println("running...")
  }
}

func main() {
  go IRunForever()

  runtime.Goexit()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment