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

前端 未结 8 905
别跟我提以往
别跟我提以往 2020-12-12 14:56

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?

8条回答
  •  死守一世寂寞
    2020-12-12 15:33

    I know this answer is so late, I have wrote this solution, Hacking Go run-time, It's not safety, It may crashes:

    import (
        "unsafe"
        "reflect"
    )
    
    
    func isChanClosed(ch interface{}) bool {
        if reflect.TypeOf(ch).Kind() != reflect.Chan {
            panic("only channels!")
        }
    
        // get interface value pointer, from cgo_export 
        // typedef struct { void *t; void *v; } GoInterface;
        // then get channel real pointer
        cptr := *(*uintptr)(unsafe.Pointer(
            unsafe.Pointer(uintptr(unsafe.Pointer(&ch)) + unsafe.Sizeof(uint(0))),
        ))
    
        // this function will return true if chan.closed > 0
        // see hchan on https://github.com/golang/go/blob/master/src/runtime/chan.go 
        // type hchan struct {
        // qcount   uint           // total data in the queue
        // dataqsiz uint           // size of the circular queue
        // buf      unsafe.Pointer // points to an array of dataqsiz elements
        // elemsize uint16
        // closed   uint32
        // **
    
        cptr += unsafe.Sizeof(uint(0))*2
        cptr += unsafe.Sizeof(unsafe.Pointer(uintptr(0)))
        cptr += unsafe.Sizeof(uint16(0))
        return *(*uint32)(unsafe.Pointer(cptr)) > 0
    }
    

    https://gist.github.com/youssifsayed/ca0cfcf9dc87905d37a4fee7beb253c2

提交回复
热议问题