Select 了解有无goroutine的频道选择

Select 了解有无goroutine的频道选择,select,go,closures,channel,goroutine,Select,Go,Closures,Channel,Goroutine,大家好,我的社区, 我正在使用Go将观察者设置为文件。我的函数看起来像 func SetWatcher(filename string) { fmt.Println("Setting watcher to file ", filename) Watcher, err = fsnotify.NewWatcher() if err != nil { fmt.Println("inotify errored. Other methods needs to be

大家好,我的社区, 我正在使用Go将观察者设置为文件。我的函数看起来像

func SetWatcher(filename string) {
    fmt.Println("Setting watcher to file ", filename)
    Watcher, err = fsnotify.NewWatcher()
    if err != nil {
        fmt.Println("inotify errored. Other methods needs to be implemented.")
        panic(err)
    }
    if err != nil {
        log.Fatal(err)
    }

    done := make(chan bool)
    go func() {
        for {
            select {
            case event := <-Watcher.Events:
                if event.Op == fsnotify.Remove {
                    fmt.Println("File removed, needs to kill the process.")
                } else if event.Op == fsnotify.Rename {
                    fmt.Println("File renamed, need to restart seeking.")
                }

            case err := <-Watcher.Errors:
                log.Println("error:", err)
            }
        }
    }()

    err = Watcher.Add(filename)
    if err != nil {
        log.Fatal(err)
    }
    <-done
}
    w := &Watcher{
    fd:       fd,
    poller:   poller,
    watches:  make(map[string]*watch),
    paths:    make(map[int]string),
    Events:   make(chan Event, 10), // Made it buffered here
    Errors:   make(chan error),
    done:     make(chan struct{}),
    doneResp: make(chan struct{}),
}
但是,如果我试图删除goroutine中运行的闭包并将其作为

func SetWatcher(filename string) {
    fmt.Println("Setting watcher to file ", filename)
    Watcher, err = fsnotify.NewWatcher()
    if err != nil {
        fmt.Println("inotify errored. Other methods needs to be implemented.")
        panic(err)
    }
    if err != nil {
        log.Fatal(err)
    }
    //defer Watcher.Close()

    //done := make(chan bool)
    //go func() {
    //  for {
            select {
            case event := <-Watcher.Events:
                if event.Op == fsnotify.Remove {
                    fmt.Println("File removed, needs to kill the process.")
                } else if event.Op == fsnotify.Rename {
                    fmt.Println("File renamed, need to restart seeking.")
                }

            case err := <-Watcher.Errors:
                log.Println("error:", err)
            }
        //}
    //}()

    err = Watcher.Add(filename)
    if err != nil {
        log.Fatal(err)
    }
    //<-done
}
而不是从频道接收并继续等待

我已经了解到这可能是由于非缓冲通道造成的。为了验证这一点,我修改了库以使用缓冲通道,生成新观察者的函数部分如下所示

func SetWatcher(filename string) {
    fmt.Println("Setting watcher to file ", filename)
    Watcher, err = fsnotify.NewWatcher()
    if err != nil {
        fmt.Println("inotify errored. Other methods needs to be implemented.")
        panic(err)
    }
    if err != nil {
        log.Fatal(err)
    }

    done := make(chan bool)
    go func() {
        for {
            select {
            case event := <-Watcher.Events:
                if event.Op == fsnotify.Remove {
                    fmt.Println("File removed, needs to kill the process.")
                } else if event.Op == fsnotify.Rename {
                    fmt.Println("File renamed, need to restart seeking.")
                }

            case err := <-Watcher.Errors:
                log.Println("error:", err)
            }
        }
    }()

    err = Watcher.Add(filename)
    if err != nil {
        log.Fatal(err)
    }
    <-done
}
    w := &Watcher{
    fd:       fd,
    poller:   poller,
    watches:  make(map[string]*watch),
    paths:    make(map[int]string),
    Events:   make(chan Event, 10), // Made it buffered here
    Errors:   make(chan error),
    done:     make(chan struct{}),
    doneResp: make(chan struct{}),
}
但行为是一样的。有人能帮我理解为什么在goroutine中,频道的阅读是有效的,而在没有goroutine的情况下是无效的


谢谢。

我对fsnotify不太熟悉,但是在调用
Watcher.Add()
来查看文件之前,它似乎不会在频道上发送任何内容,但是在第二个版本中,
Watcher.Add()
发生在
选择
之后。在这种情况下,select将永远被阻止,因为没有任何东西会被通知为未调用
Watcher.Add()
。因此出现了僵局