A Tour of Go - Concurrency Flashcards

1
Q

What is a goroutine?

A

A goroutine is a lightweight thread managed by the Go runtime.

go f(x, y, z)

starts a new goroutine running

f(x, y, z)

The evaluation of f, x, y, and z happens in the current goroutine and the execution of f happens in the new goroutine.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Do goroutines share an address space?

A

Yes, so access to shared memory must be synchronised. The sync package provides useful primitives.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is a channel?

A

Channels are typed conduits through which you can send and receive values with the channel operator <-.

ch <- v     // Send v to channel sh
v := <-ch  // Receive from ch, and 
                 // assign value to v
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

How you do create a channel?

A

Like maps and slices, channels must be created before use:

ch := make(chan int)

By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is a buffered channel?

A

Channels can be buffered. Provide the buffer length as a second argument to make to initialise a buffered channel:

ch := make(chan int, 100)

Sends to a buffered channel block only when the buffer is full.

Receives block when the buffer is empty.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How does a sender close a channel?

A

Using the close built-in:

close(c)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How can you check if a channel has been closed?

A

Receivers can test whether a channel has been closed by assigning a second parameter to the receive expression:

v, ok := <-ch

ok is false if there are no more values to receive and the channel is closed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Can the range form of the for loop be used on a channel?

A

Yes,

for i := range c

The loop receives values from the channel repeatedly until it is closed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Can you send to a closed channel?

A

Only the sender should close a channel, never a receiver. Sending on a closed channel will cause a panic.

Channels aren’t like files; you don’t usually need to close them. Closing is only necessary when the receiver must be told there are no more values coming, such as to terminate a range loop.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is a select statement?

A

The select statement lets a goroutine wait on multiple communication operations.

select {
    case c <- x:
        x, y = y, x+y
    case <-quit:
         fmt.Println("quit")
     return
}

A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Give an example of fibonacci using goroutines, channels and select.

A
package main

import "fmt"

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c)
		}
		quit <- 0
	}()
	fibonacci(c, quit)
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How does the default case in a select statement work?

A

The default case in a select is run if no other case is ready.

Use a default case to try a send or receive without blocking:

select {
case i := <-c:
    // use i
default:
    // receiving from c would block
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is mutual exclusion?

A

Making sure only one goroutine can access a variable at one time to avoid conflicts.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How does Go support mutual exclusion?

A

The data structure that provides mutual exclusion is called a mutex.

Go’s standard library provides mutual exclusion with sync.Mutex and its two methods:

  • Lock
  • Unlock

We can define a block of code to be executed in mutual exclusion by surrounding it with a call to Lock and Unlock.

defer can be used to ensure the mutex will be unlocked.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly