Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching return values from goroutines

The below code gives compilation error saying 'unexpected go':

x := go doSomething(arg)  func doSomething(arg int) int{     ...     return my_int_value } 

I know, I can fetch the return value if I call the function normally i.e. without using goroutine or I can use channels etc.

My question is why is it not possible to fetch a return value like this from a goroutine.

like image 608
Nerve Avatar asked Jan 06 '14 07:01

Nerve


People also ask

Can Goroutines return values?

Channels provide synchronization and communication between goroutines. You can send the return value in a channel in the goroutine and then collect that value in the main function. This line will wait until a value is pushed to the result channel.

How do you communicate between two Goroutines?

A channel allows one goroutine to signal another goroutine about a particular event. Before going any further, let's look at a quick example where channels are used to get the sum of a slice by concurrently distributing the work across two goroutines.

Do Goroutines share variables?

One of the invariants is "no goroutine is accessing the shared variables", but there may be additional invariants specific to the data structures that the mutex guards.

Can you do something in Goroutines without channels?

Channels not only work for interactions between a goroutine and the main programs, they also provide a way to communicate between different goroutine. For example, let's create a function that subtracts 3 to every result returned by timesThree but only if it's an even number.


1 Answers

Why is it not possible to fetch a return value from a goroutine assigning it to a variable?

Run goroutine (asynchronously) and fetch return value from function are essentially contradictory actions. When you say go you mean "do it asynchronously" or even simpler: "Go on! Don't wait for the function execution be finished". But when you assign function return value to a variable you are expecting to have this value within the variable. So when you do that x := go doSomething(arg) you are saying: "Go on, don't wait for the function! Wait-wait-wait! I need a returned value be accessible in x var right in the next line below!"

Channels

The most natural way to fetch a value from a goroutine is channels. Channels are the pipes that connect concurrent goroutines. You can send values into channels from one goroutine and receive those values into another goroutine or in a synchronous function. You could easily obtain a value from a goroutine not breaking concurrency using select:

func main() {      c1 := make(chan string)     c2 := make(chan string)      go func() {         time.Sleep(time.Second * 1)         c1 <- "one"     }()     go func() {         time.Sleep(time.Second * 2)         c2 <- "two"     }()      for i := 0; i < 2; i++ {         // Await both of these values         // simultaneously, printing each one as it arrives.         select {         case msg1 := <-c1:             fmt.Println("received", msg1)         case msg2 := <-c2:             fmt.Println("received", msg2)         }      } } 

The example is taken from Go By Example

CSP & message-passing

Go is largerly based on CSP theory. The naive description from above could be precisely outlined in terms of CSP (although I believe it is out of scope of the question). I strongly recommend to familiarize yourself with CSP theory at least because it is RAD. These short quotations give a direction of thinking:

As its name suggests, CSP allows the description of systems in terms of component processes that operate independently, and interact with each other solely through message-passing communication.

In computer science, message passing sends a message to a process and relies on the process and the supporting infrastructure to select and invoke the actual code to run. Message passing differs from conventional programming where a process, subroutine, or function is directly invoked by name.

like image 52
I159 Avatar answered Oct 04 '22 15:10

I159