Help for the VSCode editor.
-
What should be the minimum size of the channel in the program to prevent any deadlock error?
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup wg.Add(2) ch := make(chan int, <size>) go produce(ch, &wg) wg.Wait() } func produce(ch chan int, wg *sync.WaitGroup) { for i := 10; i <= 100; i += 10 { ch <- i } fmt.Println("Exiting Produce") close(ch) go consume(ch, wg) wg.Done() } func consume(ch chan int, wg *sync.WaitGroup) { for val := range ch { fmt.Println("Received: ", val) } fmt.Println("Exiting Consume") wg.Done() }
- 10
- 5
- 9
- 15
Reveal
10
- Look at the
for
loop in theproduce
function. This will iterate 10 times, placing 10 values into the channel before any are read back from the channel. - If the buffer is less than 10, then the channel insert within the
for
loop will block. - Since no other code is running at this point, it is a deadlock.
-
What would be the output for the following code?
package main import "fmt" func consume(ch chan int) { for { select { case num := <-ch: fmt.Printf("%d ", num) break } } } func main() { ch := make(chan int) go consume(ch) for i := 0; i < 5; i++ { ch <- i } }
(TODO - Await clickup resolution)
- 0
- Nondeterministic
- 0 1 2 3 4 5
- 0 1 2 3
Reveal
0 1 2 3 4
- Channels operate as first-in first-out queues
- The
consume
goroutine is started before we start writing to the channel, so it will block until a value is ready. - We are only using the one channel so the
consume
function will read out the numbers in the order they were inserted.
-
What should be the order of statements to prevent the error in the below code?
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup // Line 1 go func() { time.Sleep(time.Millisecond) fmt.Println("Inside Goroutine") // Line 2 }() // Line 3 }
- wg.Add(1)
wg.Done()
wg.Wait() - wg.Add(1)
wg.Add(1)
wg.Done()
wg.Wait() - wg.Add(1)
wg.Wait()
wg.Done() - wg.Add(2)
wg.Done()
wg.Wait()
Reveal
wg.Add(1)
wg.Done()
wg.Wait()- We can eliminate one possible answer immediately. We have 3 statements to insert, not 4.
- With wait groups, we need to add the number of routines we are going to wait on before we start the goroutines. This means we can eliminate
wg.Add(2)
andLine 1
must therefore bewg.Add(1)
. - At the end of a goroutine, use
wg.Done()
to decrement the wait count, so that'sLine 2
. - Finally, the function that needs to block until goroutines complete needs to call
wg.Wait()
, so that'sLine 3
.
- wg.Add(1)
-
Select the correct behavior for the following program:
package main import ( "sync" ) func main() { ch := make(chan int) var wg sync.WaitGroup wg.Add(1) go func() { ch <- 1 // Line 10 wg.Done() // Line 11 }() wg.Wait() close(ch) <-ch }
- The program runs successfully
- The program consists of syntax error on line 11
- The program creates a panic situation on line 10
- The program ends in a deadlock, causing a fatal error
Reveal
The program ends in a deadlock, causing a fatal error
- The wait group
Add
,Done
andWait
all appear to be in the right places as per the previous question. - However the goroutine is writing to an unbuffered channel. Since nothing is reading that channel,
ch <- 1
will block, and the goroutine will not reachwg.Done()
- Deadlock will occur when
main
reacheswg.Wait()
as both it and the goroutine are blocked.
We could fix this by buffering the channel:
ch := make(chan int, 1)
-
Why does the following program fail?
package main import ( "fmt" "sync" ) func main() { var c chan int var wg sync.WaitGroup wg.Add(2) go func() { c <- 1 wg.Done() }() go func() { val := <-c fmt.Println(val) wg.Done() }() wg.Wait() }
- Send on a "nil" channel is blocked.
- Inconsistent use of wait groups inside the "go-routines".
- Receive on a "nil" channel is blocked.
- Sending to and receiving from a "nil" channel blocks forever.
Reveal
Sending to and receiving from a "nil" channel blocks forever.
- Both goroutines are blocked because the channel
c
isnil
wg.Done()
is never called in either routinewg.Wait()
causes a deadlock.
We could fix this by initializing the channel. It doesn't need buffering because the second goroutine will read the value inserted by the first, and both will get to
wg.Done()
var c = make(chan int)
-
What happens when you write to an unbuffered, closed channel?
- Block until something is read from the channel
- Hang forever
- Works
- Panic Situation
Reveal
Panic Situation
-
What happens if you read from an unbuffered, closed channel?
- Panic situation
- Works
- Returns zero value
- Block until something is written to the channel
Reveal
Returns zero value
- Zero being whatever that means for the type associated with the channel, i.e.
0
for all numeric types,""
for strings,false
for booleans etc.
-
Select all the correct options for a nil channel.
- Read operation blocks forever.
- Write operation blocks forever.
- Read operations works and returns a zero value.
- Close operation creates a panic situation.
Reveal
A, B, D
- We know A and B are true from Q5.
- If A is true, then C cannot possibly be true.