# How do goroutines work?

## Issue

I was following the Go Tour and I am a bit stuck when it comes to goroutines. I understand that they are very lightweight and that every time a goroutine blocks, another one will start but I can’t get my head around how this example actually works:

``````package main

import (
"fmt"
"time"
)

func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(1000 * time.Millisecond)
fmt.Println(s)
}
}

func main() {
go say("world")
say("hello")
}
``````

Playground

I understand that a goroutine is started for the say function with the argument “world”, but as far as I understand that should print “world” five times and “hello” once. However I don’t understand why the output is as it is:

``````hello
world
hello
world
hello
world
hello
world
hello
``````

From my limited understanding of threads from other languages the output should have been something like this:

``````hello
world
world
world
world
world
``````

or like this:

``````world
world
world
hello
world
world
``````

Why does the second line execute five times as well? Does anything below a `go` statement classify as part of the go routine?

Also the next slide shows something I can’t get my head round again:

``````package main

import "fmt"

func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}

func main() {
a := []int{7, 2, 8, -9, 4, 0}

c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c

fmt.Println(x, y, x+y)
}
``````

Playground

A goroutine is started for the second half of the slice and then another one for the first part of the slice, however the values `x` and `y` have been assigned two different values. The way I see it the `sum` function will send it’s sum to channel `c` and then the next `sum` will send it’s sum to the same channel `c` so how can the two variables be assigned two different values? Shouldn’t channel `c` have one single `sum` value in there?

I appreciate that this is quite a long question but I wasn’t able to find the answer to these questions.

## Solution

Why does the second line execute 5 times as well?

The second line will print `hello` every second 5 times in the `main()` thread.
But concurrently the first line `go say("world")` will also print world every seconds five times in a separate goroutine.
The `Sleep` ensure that each routine yields, allowing the other to resume.

Hence the output:

``````hello
world
hello
world
hello
world
hello
world
hello
``````

The way I see it the sum function will send it’s sum to channel c and then the next sum will send it’s sum to the same channel c so how can the two variables be assigned two different values?

Because each send will block on `c` until channel `c` is read.
Since there are two write to `c`, you need to read:

`````` x, y := <-c, <-c // receive from c twice.
``````

The Assignement section of Golang Spec allows for a tuple assignment if:

the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the `nth` expression on the right is assigned to the nth operand on the left.