How can I have two goroutines of the same function which look at each others' values?

Issue

I am trying to achieve a function which I can call with two goroutines and different parameters. Each will manipulate its own string, and they will send their strings to each other through a channel and compare results. Here is my attempt at this (Go Playground linked) :

func swap_values(str string, strChan1 chan string, strChan2 chan string, done chan bool) {
  str += "test"
  strChan1 <- str
  <-strChan2
  done <- true
}

and this is deadlocking. For my two calls to the function, I swap the channels so strChan1 is a different channel for each. How can I fix this to not deadlock and accomplish what I want? Again, I will be comparing the strings and doing additional manipulation, this is just a proof of concept for getting both.

Solution

It is deadlocking because both goroutines try to write to channels that nobody is listening to. The first goroutine tries to write one channel, and since the second is not reading from it, it is stuck there. The second goroutine does the same, so they both stop, waiting for each other.

Simplest way to deal with this is to use a channel with size 1, so write can proceed without waiting for a reader.

strChan1 := make(chan string,1)
strChan2 := make(chan string,1)

If you have to use 0-length channels, you need to use a select to accommodate different orderings of the goroutines:

select {
  case strChan1 <- str:
     <-strChan2
  case <-strChan2:
     strChan1 <- str
}

Answered By – Burak Serdar

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.