HiveBrain v1.2.0
Get Started
← Back to all entries
snippetgoCritical

How to check a channel is closed or not without reading it?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
readinghowcheckchannelnotwithoutclosed

Problem

This is a good example of workers & controller mode in Go written by @Jimt, in answer to
"Is there some elegant way to pause & resume any other goroutine in golang?"

```
package main

import (
"fmt"
"runtime"
"sync"
"time"
)

// Possible worker states.
const (
Stopped = 0
Paused = 1
Running = 2
)

// Maximum number of workers.
const WorkerCount = 1000

func main() {
// Launch workers.
var wg sync.WaitGroup
wg.Add(WorkerCount + 1)

workers := make([]chan int, WorkerCount)
for i := range workers {
workers[i] = make(chan int)

go func(i int) {
worker(i, workers[i])
wg.Done()
}(i)
}

// Launch controller routine.
go func() {
controller(workers)
wg.Done()
}()

// Wait for all goroutines to finish.
wg.Wait()
}

func worker(id int, ws <-chan int) {
state := Paused // Begin in the paused state.

for {
select {
case state = <-ws:
switch state {
case Stopped:
fmt.Printf("Worker %d: Stopped\n", id)
return
case Running:
fmt.Printf("Worker %d: Running\n", id)
case Paused:
fmt.Printf("Worker %d: Paused\n", id)
}

default:
// We use runtime.Gosched() to prevent a deadlock in this case.
// It will not be needed of work is performed here which yields
// to the scheduler.
runtime.Gosched()

if state == Paused {
break
}

// Do actual work here.
}
}
}

// controller handles the current state of all workers. They can be
// instructed to be either running, paused or stopped entirely.
func controller(workers []chan int) {
// Start workers
for i := range workers {
workers[i] <- Running
}

// Pause workers.
<-time.After(1e9)
for i := range workers {
wor

Solution

In a hacky way it can be done for channels which one attempts to write to by recovering the raised panic. But you cannot check if a read channel is closed without reading from it.

Either you will

  • eventually read the "true" value from it (v



  • read the "true" value and 'not closed' indicator (v, ok



  • read a zero value and the 'closed' indicator (v, ok



  • will block in the channel read forever (v



Only the last one technically doesn't read from the channel, but that's of little use.

Context

Stack Overflow Q#16105325, score: 107

Revisions (0)

No revisions yet.