Multithreading in Go. Can somebody explain these answers to me?

user2399525

I got two questions on a mock-exam. I was given the answers but cannot figure out the rationale behind them.

I will first post the code and then the questions and answers. Maybe somebody would be so kind to explain the answers to me?

package main

import "fmt"

func fact(n int, c chan int, d chan int) {

    k := /* code to compute factorial of n */

    z := <- d

    c <- k + z

    d <- z + 1

}

func main() {

    r := 0

    c := make(chan int)
    d := make(chan int)

    for i = 0 ; i < N ; i++ {
        go fact(i,c,d)
    }

    d <- 0

    for j = 0 ; j < N ; j++ {
        r = r + <-c
    }

    fmt.Printf("result = %d\n",r)

}

The first question is:

How does the program behave if we omit the line "d <- 0" in the main procedure, and why?

The answer from the teacher is:

The state of all the threads are blocked and also the main thread.

The second question is:

How would the efficiency of the whole program be affected if we swapped the first two lines of the fact procedure?

The answer is:

All threads are going to run sequentially. Each thread would trigger another thread only when it is finished.

Rob Napier

It is best not to think of this as "multi-threading." Go provides direct facilities for concurrency, not for threading. It happens to implement its concurrency with threading, but that is an implementation detail. See Rob Pike's talk, Concurrency is not parallelism for a much deeper discussion.

The key to your questions is that channels are synchronous by default (if they are not made buffered during their construction). When one goroutine writes to a channel, it will block until some other goroutine reads from that channel. So when this line executes:

z := <- d

It cannot proceed until this line executes:

d <- 0

Without some value being available on the d channel, fact will never proceed. That is likely obvious to you. But the reverse is also true. Until something reads from the d channel, the main goroutine cannot proceed. In this way unbuffered channels provide a synchronization point across concurrent goroutines.

Similarly, the main loop cannot proceed until some value appears on c. I find it useful to use two fingers and point to the current line of code in each goroutine. Advance one finger until you get to a channel operation. Then advance the other until it reaches a channel operation. If your fingers are pointing to a read and a write on the same channel, then you may proceed. If they are not, then you're in deadlock.

If you think this through, you'll discover a problem. This program leaks a goroutine.

func fact(n int, c chan int, d chan int) {
    k := /* code to compute factorial of n */
    z := <- d // (1)
    c <- k + z
    d <- z + 1 // (2)
}

At (2) we try to write to d. What will allow that to proceed? Another goroutine reading from d. Remember, we started N goroutines, and all of them tried to read from d. Only one of them will be successful. The others will block at (1), waiting for something to show up on d. That happens when the first one gets to (2). Then that goroutine exits and a random goroutine will proceed.

But there will be a final goroutine that will never be able to write to d and it will leak. In order to resolve that, the following would need to be added before the final Printf:

<-d

This would allow the last goroutine to exit.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Can somebody explain this javascript statement to me?

From Dev

Can somebody explain me the working of this program with stacks?

From Dev

Can somebody explain the Output?

From Dev

Can somebody explain me what is the use of "etag" in django?

From Dev

Can somebody please briefly explain to me what's happening with the IntStream?

From Dev

Can somebody explain to me what 'void postConcat' in Android does?

From Dev

Can somebody explain to me why the L (long) has to be there?

From Dev

Somebody explain me the render in flask

From Dev

Can somebody please explain WaitForSeconds()?

From Dev

Can somebody explain these C code?

From Dev

Can somebody explain an exclamation mark?

From Dev

Can somebody explain these lines in this code?

From Dev

can somebody explain me what does "passing by value" and "Passing by reference" mean in C#?

From Dev

Reassigning global variable in JavaScript - Can somebody explain to me why currentAcc stays undefined

From Dev

Reassigning global variable in JavaScript - Can somebody explain to me why currentAcc stays undefined

From Dev

Reassigning global variable in JavaScript - Can somebody explain to me why currentAcc stays undefined

From Dev

Can somebody explain this piece of clojure code?

From Dev

Can somebody explain i+++x?

From Dev

Can somebody explain how to use ASyncTask with Android?

From Dev

Can somebody explain the logic for inorder tree travesal?

From Dev

Can somebody explain this "stop in" syntax in Swift?

From Dev

Can somebody explain the logic of .indexOf() in Javascript?

From Dev

Can somebody explain the AngularJs animation nomenclature?

From Dev

Can somebody explain my cmd output

From Dev

Can somebody explain this changing `du` output?

From Dev

Can somebody explain the last method in this code?

From Dev

Can somebody explain what this piece of twisted does?

From Dev

What is the role of if statements in this code can somebody explain?

From Dev

Somebody explain to me why we never write directly to state in Redux?

Related Related

  1. 1

    Can somebody explain this javascript statement to me?

  2. 2

    Can somebody explain me the working of this program with stacks?

  3. 3

    Can somebody explain the Output?

  4. 4

    Can somebody explain me what is the use of "etag" in django?

  5. 5

    Can somebody please briefly explain to me what's happening with the IntStream?

  6. 6

    Can somebody explain to me what 'void postConcat' in Android does?

  7. 7

    Can somebody explain to me why the L (long) has to be there?

  8. 8

    Somebody explain me the render in flask

  9. 9

    Can somebody please explain WaitForSeconds()?

  10. 10

    Can somebody explain these C code?

  11. 11

    Can somebody explain an exclamation mark?

  12. 12

    Can somebody explain these lines in this code?

  13. 13

    can somebody explain me what does "passing by value" and "Passing by reference" mean in C#?

  14. 14

    Reassigning global variable in JavaScript - Can somebody explain to me why currentAcc stays undefined

  15. 15

    Reassigning global variable in JavaScript - Can somebody explain to me why currentAcc stays undefined

  16. 16

    Reassigning global variable in JavaScript - Can somebody explain to me why currentAcc stays undefined

  17. 17

    Can somebody explain this piece of clojure code?

  18. 18

    Can somebody explain i+++x?

  19. 19

    Can somebody explain how to use ASyncTask with Android?

  20. 20

    Can somebody explain the logic for inorder tree travesal?

  21. 21

    Can somebody explain this "stop in" syntax in Swift?

  22. 22

    Can somebody explain the logic of .indexOf() in Javascript?

  23. 23

    Can somebody explain the AngularJs animation nomenclature?

  24. 24

    Can somebody explain my cmd output

  25. 25

    Can somebody explain this changing `du` output?

  26. 26

    Can somebody explain the last method in this code?

  27. 27

    Can somebody explain what this piece of twisted does?

  28. 28

    What is the role of if statements in this code can somebody explain?

  29. 29

    Somebody explain to me why we never write directly to state in Redux?

HotTag

Archive