Skip to content

Latest commit

 

History

History
101 lines (71 loc) · 2.52 KB

File metadata and controls

101 lines (71 loc) · 2.52 KB

Concurrency

Go has excellent support for concurrency. It uses two primitives to do that - goroutines and channels.

goroutines

goroutines are "light weight" threads. They start with a 2Kb stack that grows with need. This allows Go to easily run thousands of goroutines on a single machine. Every time our we server get a new connection, it spins a new goroutine to handle it.

Here's a simple example:

func Printer(name string) {
	fmt.Println("Hi, I'm", name)
}

func main() {
	names := []string{"Bugs", "Daffy", "Elmer"}

	for _, name := range names {
		go Printer(name)
	}

	// Wait for the goroutines to finish (there are better ways, see sync.WaitGroup)
	time.Sleep(time.Millisecond)
}

Go's basic data structures are not "goroutine safe", which means that when you modify them from two goroutines at the same time - something bad will happen.

To guard our data structures we can use sync.Mutex which ensures that only one goroutines modifies a data structure at a point in time.

There are other ways to do concurrency in Go, such as atomic changes and channels. But we won't get there this time.

Structs

Sometimes we'd like to define out own data types. In this case we'll use a struct which is a set of named fields, each with it's own type.

Let's define a Loon struct that will have a name and an age.

type Loon struct {
	Name string
	Age  int
}

We can create structs by passing fields in orders.

	elmer := Loon{"Elmer", 80}

or we can specify the field names

	daffy := Loon{
		Age:  80,
		Name: "Daffy",
	}

We don't have constructors in Go, instead we write a function that creates a new struct and return it. This function is usually called New<Type>

func NewLoon(name string, age int) *Loon {
	return &Loon{name, age}
}

We return a pointer to the object we created, so we can reference it and not copy it over.

People coming from C/C++ will see a bug in NewLoon since it returns a pointer to an object allocated on the stack. The Go compiler does what's called "escape analysis" and sees that we return a pointer to the new allocated Loon so it'll create it on the heap.

structs can also have methods, embed others and much more. But we won't get into that this time.

Exercise

Change our db to be a struct that holds the map and also a sync.Mutex. Every time we access the data, Lock the mutex, make sure to Unlock when you're done.

Solution