I don't think basic use of pthreads is that different in complexity from goroutines but it's neat to see lightweight threads as a built-in language feature. goroutine usage superficially looks a lot like costates in Dynamic C, a proprietary nonstandard compiler for the Rabbit series of Z80 derived CPUs from Digi International. It's a really useful feature on a single core 8-bit microcontroller that frees you having "one big loop" with brittle timing in an embedded application.
Code:
package main
import (
"fmt"
"runtime"
"time"
)
func thread1(counter chan int) {
count := 0
for {
fmt.Println("Hello from thread 1")
runtime.Gosched() // force yield
time.Sleep(5 * time.Second)
count++
counter <- count
}
}
func thread2(counter chan int) {
count := 0
for {
fmt.Println("Hello from thread 2")
runtime.Gosched() // force yield
time.Sleep(5 * time.Second)
count++
counter <- count
}
}
func main() {
c1 := make(chan int)
c2 := make(chan int)
go thread1(c1)
go thread2(c2)
for {
count1 := <-c1
count2 := <-c2
fmt.Println("main() is alive ", count1, count2)
time.Sleep(5 * time.Second)
runtime.Gosched() // force yield
}
}
Output:
Hello from thread 1
Hello from thread 2
Hello from thread 1
Hello from thread 2
main() is alive 1 1
Hello from thread 2
Hello from thread 1
main() is alive 2 2
main() is alive 3 3
Hello from thread 2
Hello from thread 1
main() is alive 4 4
Hello from thread 2
Hello from thread 1
main() is alive 5 5
Hello from thread 2
Hello from thread 1
main() is alive 6 6
Hello from thread 1
Hello from thread 2