throw: all goroutines are asleep - deadlock - multithreading

Given the following simple Go program
package main
import (
"fmt"
)
func total(ch chan int) {
res := 0
for iter := range ch {
res += iter
}
ch <- res
}
func main() {
ch := make(chan int)
go total(ch)
ch <- 1
ch <- 2
ch <- 3
fmt.Println("Total is ", <-ch)
}
I am wondering if someone can enlighten me as to why I get
throw: all goroutines are asleep - deadlock!
thank you

As you never close the ch channel, the range loop will never finish.
You can't send back the result on the same channel. A solution is to use a different one.
Your program could be adapted like this :
package main
import (
"fmt"
)
func total(in chan int, out chan int) {
res := 0
for iter := range in {
res += iter
}
out <- res // sends back the result
}
func main() {
ch := make(chan int)
rch := make(chan int)
go total(ch, rch)
ch <- 1
ch <- 2
ch <- 3
close (ch) // this will end the loop in the total function
result := <- rch // waits for total to give the result
fmt.Println("Total is ", result)
}

This is also right.
package main
import "fmt"
func main() {
c := make(chan int)
go do(c)
c <- 1
c <- 2
// close(c)
fmt.Println("Total is ", <-c)
}
func do(c chan int) {
res := 0
// for v := range c {
// res = res + v
// }
for i := 0; i < 2; i++ {
res += <-c
}
c <- res
fmt.Println("something")
}

Related

How can I fix the deadlock?

The programm must print sqrt of num if I write to first channel, 3*num if to secon, complete if to stop. I can't understand where is channel blocked.
package main
import (
"fmt"
)
func main() {
ch1, ch2 := make(chan int), make(chan int)
stop := make(chan struct{})
r := calculator(ch1, ch2, stop)
//ch1 <- 3
ch2 <- 2
//<-stop
fmt.Println(<-r)
}
func calculator(firstChan <-chan int, secondChan <-chan int, stopChan <-chan struct{}) <-chan int {
returnChan := make(chan int)
go func() {
defer close(returnChan)
select {
case <-firstChan:
returnChan <- (<-firstChan) * (<-firstChan)
case <-secondChan:
returnChan <- (<-secondChan) * 3
case <-stopChan:
close(returnChan)
}
}()
return returnChan
}
You are reading from the case statement:
case <-firstChan
and within case block:
...(<-firstChan) * (<-firstChan)
all together you read three times when only one was sent into the channel.
Get the value to a var in the case statement and use it in the block like below:
func calculator(firstChan <-chan int, secondChan <-chan int, stopChan <-chan struct{}) <-chan int {
returnChan := make(chan int)
go func() {
defer close(returnChan)
select {
case firstChanVal := <-firstChan:
returnChan <- firstChanVal * firstChanVal
case firstChanVal := <-secondChan:
returnChan <- firstChanVal * 3
case <-stopChan:
close(returnChan)
}
}()
return returnChan
}
Go play ground demo
When you call <-firstChan, the program will be paused and wait for a value to send to firstChan, you call 3 times <-firstChan while you only send 1 time, the program will pause forever

Go channel takes each letter as string instead of the whole string

I'm creating a simple channel that takes string values. But apparently I'm pushing each letter in the string instead of the whole string in each loop.
I'm probably missing something very fundamental. What am I doing wrong ?
https://play.golang.org/p/-6E-f7ALbD
Code:
func doStuff(s string, ch chan string) {
ch <- s
}
func main() {
c := make(chan string)
loops := [5]int{1, 2, 3, 4, 5}
for i := 0; i < len(loops); i++ {
go doStuff("helloooo", c)
}
results := <-c
fmt.Println("channel size = ", len(results))
// print the items in channel
for _, r := range results {
fmt.Println(string(r))
}
}
Your code sends strings on the channel properly:
func doStuff(s string, ch chan string){
ch <- s
}
The problem is at the receiver side:
results := <- c
fmt.Println("channel size = ", len(results))
// print the items in channel
for _,r := range results {
fmt.Println(string(r))
}
results will be a single value received from the channel (the first value sent on it). And you print the length of this string.
Then you loop over this string (results) using a for range which loops over its runes, and you print those.
What you want is loop over the values of the channel:
// print the items in channel
for s := range c {
fmt.Println(s)
}
This when run will result in a runtime panic:
fatal error: all goroutines are asleep - deadlock!
Because you never close the channel, and a for range on a channel runs until the channel is closed. So you have to close the channel sometime.
For example let's wait 1 second, then close it:
go func() {
time.Sleep(time.Second)
close(c)
}()
This way your app will run and quit after 1 second. Try it on the Go Playground.
Another, nicer solution is to use sync.WaitGroup: this waits until all goroutines are done doing their work (sending a value on the channel), then it closes the channel (so there is no unnecessary wait / delay).
var wg = sync.WaitGroup{}
func doStuff(s string, ch chan string) {
ch <- s
wg.Done()
}
// And in main():
for i := 0; i < len(loops); i++ {
wg.Add(1)
go doStuff("helloooo", c)
}
go func() {
wg.Wait()
close(c)
}()
Try this one on the Go Playground.
Notes:
To repeat something 5 times, you don't need that ugly loops array. Simply do:
for i := 0; i < 5; i++ {
// Do something
}
The reason you are getting back the letters instead of string is that you are assigning the channel result to a variable and iterating over the result of the channel assigned to this variable which in your case is a string, and in Go you can iterate over a string with a for range loop to get the runes.
You can simply print the channel without to iterate over the channel result.
package main
import (
"fmt"
)
func doStuff(s string, ch chan string){
ch <- s
}
func main() {
c := make(chan string)
loops := [5]int{1,2,3,4,5}
for i := 0; i < len(loops) ; i++ {
go doStuff("helloooo", c)
}
results := <- c
fmt.Println("channel size = ", len(results))
fmt.Println(results) // will print helloooo
}

Synchronisation of threads in Go lang

I want to understand a bit more about how synchronisation of threads works in go. Below here I've have a functioning version of my program which uses a done channel for syncronization.
package main
import (
. "fmt"
"runtime"
)
func Goroutine1(i_chan chan int, done chan bool) {
for x := 0; x < 1000000; x++ {
i := <-i_chan
i++
i_chan <- i
}
done <- true
}
func Goroutine2(i_chan chan int, done chan bool) {
for x := 0; x < 1000000; x++ {
i := <-i_chan
i--
i_chan <- i
}
done <- true
}
func main() {
i_chan := make(chan int, 1)
done := make(chan bool, 2)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine1(i_chan, done)
go Goroutine2(i_chan)
<-done
<-done
Printf("This is the value of i:%d\n", <-i_chan)
}
However when I try to run it with out any synchronisation. Using a wait statement and no channel to specify when it's done so no synchronisation.
const MAX = 1000000
func Goroutine1(i_chan chan int) {
for x := 0; x < MAX-23; x++ {
i := <-i_chan
i++
i_chan <- i
}
}
func main() {
i_chan := make(chan int, 1)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine1(i_chan)
go Goroutine2(i_chan)
time.Sleep(100 * time.Millisecond)
Printf("This is the value of i:%d\n", <-i_chan)
}
It'll print out the wrong value of i. If you extend the wait for let say 1 sec it'll finish and print out the correct statement. I kind of understand that it has something with both thread not being finished before you print what's on the i_chan I'm just a bit curious about how this works.
Note that your first example would deadlock, since it never calls GoRoutine2 (the OP since edited the question).
If it calls GoRoutine2, then the expected i value is indeed 0.
Without synchronization, (as in this example), there is no guarantee that the main() doesn't exit before the completion of Goroutine1() and Goroutine2().
For a 1000000 loop, a 1 millisecond wait seems enough, but again, no guarantee.
func main() {
i_chan := make(chan int, 1)
i_chan <- 0
runtime.GOMAXPROCS(runtime.NumCPU())
go Goroutine2(i_chan)
go Goroutine1(i_chan)
time.Sleep(1 * time.Millisecond)
Printf("This is the value of i:%d\n", <-i_chan)
}
see more at "How to Wait for All Goroutines to Finish Executing Before Continuing", where the canonical way is to use the sync package’s WaitGroup structure, as in this runnable example.

Split string by length in Golang

Does anyone know how to split a string in Golang by length?
For example to split "helloworld" after every 3 characters, so it should ideally return an array of "hel" "low" "orl" "d"?
Alternatively a possible solution would be to also append a newline after every 3 characters..
All ideas are greatly appreciated!
Make sure to convert your string into a slice of rune: see "Slice string into letters".
for automatically converts string to rune so there is no additional code needed in this case to convert the string to rune first.
for i, r := range s {
fmt.Printf("i%d r %c\n", i, r)
// every 3 i, do something
}
r[n:n+3] will work best with a being a slice of rune.
The index will increase by one every rune, while it might increase by more than one for every byte in a slice of string: "世界": i would be 0 and 3: a character (rune) can be formed of multiple bytes.
For instance, consider s := "世a界世bcd界efg世": 12 runes. (see play.golang.org)
If you try to parse it byte by byte, you will miss (in a naive split every 3 chars implementation) some of the "index modulo 3" (equals to 2, 5, 8 and 11), because the index will increase past those values:
for i, r := range s {
res = res + string(r)
fmt.Printf("i %d r %c\n", i, r)
if i > 0 && (i+1)%3 == 0 {
fmt.Printf("=>(%d) '%v'\n", i, res)
res = ""
}
}
The output:
i 0 r 世
i 3 r a <== miss i==2
i 4 r 界
i 7 r 世 <== miss i==5
i 10 r b <== miss i==8
i 11 r c ===============> would print '世a界世bc', not exactly '3 chars'!
i 12 r d
i 13 r 界
i 16 r e <== miss i==14
i 17 r f ===============> would print 'd界ef'
i 18 r g
i 19 r 世 <== miss the rest of the string
But if you were to iterate on runes (a := []rune(s)), you would get what you expect, as the index would increase one rune at a time, making it easy to aggregate exactly 3 characters:
for i, r := range a {
res = res + string(r)
fmt.Printf("i%d r %c\n", i, r)
if i > 0 && (i+1)%3 == 0 {
fmt.Printf("=>(%d) '%v'\n", i, res)
res = ""
}
}
Output:
i 0 r 世
i 1 r a
i 2 r 界 ===============> would print '世a界'
i 3 r 世
i 4 r b
i 5 r c ===============> would print '世bc'
i 6 r d
i 7 r 界
i 8 r e ===============> would print 'd界e'
i 9 r f
i10 r g
i11 r 世 ===============> would print 'fg世'
Here is another variant playground.
It is by far more efficient in terms of both speed and memory than other answers. If you want to run benchmarks here they are benchmarks. In general it is 5 times faster than the previous version that was a fastest answer anyway.
func Chunks(s string, chunkSize int) []string {
if len(s) == 0 {
return nil
}
if chunkSize >= len(s) {
return []string{s}
}
var chunks []string = make([]string, 0, (len(s)-1)/chunkSize+1)
currentLen := 0
currentStart := 0
for i := range s {
if currentLen == chunkSize {
chunks = append(chunks, s[currentStart:i])
currentLen = 0
currentStart = i
}
currentLen++
}
chunks = append(chunks, s[currentStart:])
return chunks
}
Please note that the index points to a first byte of a rune on iterating over a string. The rune takes from 1 to 4 bytes. Slicing also treats the string as a byte array.
PREVIOUS SLOWER ALGORITHM
The code is here playground. The conversion from bytes to runes and then to bytes again takes a lot of time actually. So better use the fast algorithm at the top of the answer.
func ChunksSlower(s string, chunkSize int) []string {
if chunkSize >= len(s) {
return []string{s}
}
var chunks []string
chunk := make([]rune, chunkSize)
len := 0
for _, r := range s {
chunk[len] = r
len++
if len == chunkSize {
chunks = append(chunks, string(chunk))
len = 0
}
}
if len > 0 {
chunks = append(chunks, string(chunk[:len]))
}
return chunks
}
Please note that these two algorithms treat invalid UTF-8 characters in a different way. First one processes them as is when second one replaces them by utf8.RuneError symbol ('\uFFFD') that has following hexadecimal representation in UTF-8: efbfbd.
Also needed a function to do this recently, see example usage here
func SplitSubN(s string, n int) []string {
sub := ""
subs := []string{}
runes := bytes.Runes([]byte(s))
l := len(runes)
for i, r := range runes {
sub = sub + string(r)
if (i + 1) % n == 0 {
subs = append(subs, sub)
sub = ""
} else if (i + 1) == l {
subs = append(subs, sub)
}
}
return subs
}
Here is another example (you can try it here):
package main
import (
"fmt"
"strings"
)
func ChunkString(s string, chunkSize int) []string {
var chunks []string
runes := []rune(s)
if len(runes) == 0 {
return []string{s}
}
for i := 0; i < len(runes); i += chunkSize {
nn := i + chunkSize
if nn > len(runes) {
nn = len(runes)
}
chunks = append(chunks, string(runes[i:nn]))
}
return chunks
}
func main() {
fmt.Println(ChunkString("helloworld", 3))
fmt.Println(strings.Join(ChunkString("helloworld", 3), "\n"))
}
An easy solution using regex
re := regexp.MustCompile((\S{3}))
x := re.FindAllStringSubmatch("HelloWorld", -1)
fmt.Println(x)
https://play.golang.org/p/mfmaQlSRkHe
I tried 3 version to implement the function, the function named "splitByWidthMake" is fastest.
These functions ignore the unicode but only the ascii code.
package main
import (
"fmt"
"strings"
"time"
"math"
)
func splitByWidthMake(str string, size int) []string {
strLength := len(str)
splitedLength := int(math.Ceil(float64(strLength) / float64(size)))
splited := make([]string, splitedLength)
var start, stop int
for i := 0; i < splitedLength; i += 1 {
start = i * size
stop = start + size
if stop > strLength {
stop = strLength
}
splited[i] = str[start : stop]
}
return splited
}
func splitByWidth(str string, size int) []string {
strLength := len(str)
var splited []string
var stop int
for i := 0; i < strLength; i += size {
stop = i + size
if stop > strLength {
stop = strLength
}
splited = append(splited, str[i:stop])
}
return splited
}
func splitRecursive(str string, size int) []string {
if len(str) <= size {
return []string{str}
}
return append([]string{string(str[0:size])}, splitRecursive(str[size:], size)...)
}
func main() {
/*
testStrings := []string{
"hello world",
"",
"1",
}
*/
testStrings := make([]string, 10)
for i := range testStrings {
testStrings[i] = strings.Repeat("#", int(math.Pow(2, float64(i))))
}
//fmt.Println(testStrings)
t1 := time.Now()
for i := range testStrings {
_ = splitByWidthMake(testStrings[i], 2)
//fmt.Println(t)
}
elapsed := time.Since(t1)
fmt.Println("for loop version elapsed: ", elapsed)
t1 = time.Now()
for i := range testStrings {
_ = splitByWidth(testStrings[i], 2)
}
elapsed = time.Since(t1)
fmt.Println("for loop without make version elapsed: ", elapsed)
t1 = time.Now()
for i := range testStrings {
_ = splitRecursive(testStrings[i], 2)
}
elapsed = time.Since(t1)
fmt.Println("recursive version elapsed: ", elapsed)
}
Not the most efficient, will work for most use-cases.
Go playground: https://play.golang.org/p/0JSqv3OMdCR
// splitBy splits a string s by int n.
func splitBy(s string, n int) []string {
var ss []string
for i := 1; i < len(s); i++ {
if i%n == 0 {
ss = append(ss, s[:i])
s = s[i:]
i = 1
}
}
ss = append(ss, s)
return ss
}
// test
s := "helloworld"
ss := splitBy(s, 3)
fmt.Println(ss)
# output
$ go run main.go
[hel low orl d]

Go channels and I/O

First function
ReadF2C
takes a filename and channel, reads from file and inputs in channel.
Second function
WriteC2F
takes 2 channels and filename, takes value of each channel and saves the lower value in the output file. I'm sure there is a few syntax errors but i'm new to GO
package main
import (
"fmt"
"bufio"
"os"
"strconv"
)
func main() {
fmt.Println("Hello World!\n\n")
cs1 := make (chan int)
var nameinput string = "input.txt"
readF2C(nameinput,cs1)
cs2 := make (chan int)
cs3 := make (chan int)
cs2 <- 10
cs2 <- 16
cs2 <- 7
cs2 <- 2
cs2 <- 5
cs3 <- 8
cs3 <- 15
cs3 <- 14
cs3 <- 1
cs3 <- 6
var nameoutput string = "output.txt"
writeC2F (nameoutput,cs2,cs3)
}
func readF2C (fn string, ch chan int){
f,err := os.Open(fn)
r := bufio.NewReader(f)
for err != nil { // not end of file
fmt.Println(r.ReadString('\n'))
ch <- r.ReadString('\n')
}
if err != nil {
fmt.Println(r.ReadString('\n'))
ch <- -1
}
}
func writeC2F(fn string, // output text file
ch1 chan int, // first input channel
ch2 chan int){
var j int = 0
var channel1temp int
var channel2temp int
f,_ := os.Create(fn)
w := bufio.NewWriter(f)
channel1temp = <-ch1
channel2temp = <-ch2
for j := 1; j <= 5; j++ {
if (channel2temp < channel1temp){
n4, err := w.WriteString(strconv.Itoa(channel1temp))
} else{
n4, err := w.WriteString(strconv.Itoa(channel2temp))
}
w.flush()
}
}
This is the error messages I get:
prog.go:38: multiple-value r.ReadString() in single-value context
prog.go:65: w.flush undefined (cannot refer to unexported field or method bufio.(*Writer)."".flush)
There are multiple errors:
1)
Unlike C, Go enforces you to have your curly braces directly after your statements. So for an if case (and the same for func), instead of doing it like this:
if (channel2temp < channel1temp)
{
use this
if channel2temp < channel1temp {
2)
There is no while in Go. Use for
for {
...
}
or
for channel1temp != null || channel2temp != null {
...
}
3)
Usage of non-declared variables. Often easy to fix by making a short variable declaration the first time you initialize the variable. So instead of:
r = bufio.NewReader(file)
use
r := bufio.NewReader(file)
4)
Trying to a assign multi-value return into a single variable. If a function returns two values and you only need one, the variable you don't want can be discarded by assigning it to _. So instead of:
file := os.Open(fn)
use
file, _ := os.Open(fn)
but best practice would be to catch that error:
file, err := os.Open(fn)
if err != nil {
panic(err)
}
There are more errors on top of this, but maybe it will get you started.
I also suggest reading Effective Go since it will explain many of the things I've just mentioned.
Edit:
And there are help online for sure. It might be a new language, but the online material is really useful. Below is a few that I used when learning Go:
Effective Go: Good document on how to write idiomatic Go code
The Go programming language Tour: Online tour of Go with interactive examples.
Go By Example: Interactive examples of Go programs, starting with Hello World.
Go Specification: Surprisingly readable for being a specification. Maybe not a start point, but very useful.

Resources