Go语言处理多类事件最优方案咨询:文件变更、定时器、信号
Go 实现多事件响应的示例
下面是一个完整的实现,通过select语句配合goroutine监听三类事件,实现无限等待并触发对应处理逻辑:
实现思路
- 为每类事件创建独立的goroutine负责监听事件源,将事件发送到对应的channel
- 主goroutine通过
select阻塞等待所有事件channel,收到事件后调用对应处理函数,完成后回到循环继续等待
完整代码
package main import ( "fmt" "os" "os/signal" "syscall" "time" "github.com/fsnotify/fsnotify" ) func main() { // 初始化文件变更事件通道 fileEventChan := make(chan fsnotify.Event) fileErrChan := make(chan error) go watchTargetFile("/path/to/your/target.txt", fileEventChan, fileErrChan) // 初始化定时器(每10秒触发一次,可按需调整) ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() // 初始化SIGUSR1信号监听通道 sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGUSR1) // 主循环:无限等待并处理事件 for { select { case event := <-fileEventChan: handleFileChange(event) case err := <-fileErrChan: fmt.Printf("文件监听出错: %v\n", err) case <-ticker.C: handleTimerExpire() case sig := <-sigChan: handleUserSignal(sig) } } } // handleFileChange 处理文件变更事件 func handleFileChange(event fsnotify.Event) { fmt.Printf("[文件变更] 路径: %s, 操作类型: %v\n", event.Name, event.Op) // 在这里添加你的文件变更处理逻辑 } // handleTimerExpire 处理定时器到期事件 func handleTimerExpire() { fmt.Println("[定时器] 到期触发") // 在这里添加你的定时器处理逻辑 } // handleUserSignal 处理SIGUSR1信号 func handleUserSignal(sig os.Signal) { fmt.Printf("[信号] 收到: %v\n", sig) // 在这里添加你的信号处理逻辑 } // watchTargetFile 启动文件监听goroutine func watchTargetFile(filePath string, eventChan chan<- fsnotify.Event, errChan chan<- error) { watcher, err := fsnotify.NewWatcher() if err != nil { errChan <- err return } defer watcher.Close() // 添加要监听的文件 if err := watcher.Add(filePath); err != nil { errChan <- err return } for { select { case event, ok := <-watcher.Events: if !ok { errChan <- fmt.Errorf("文件监听通道已关闭") return } // 仅处理文件写入/修改事件,可按需添加创建、删除等操作 if event.Has(fsnotify.Write) { eventChan <- event } case err, ok := <-watcher.Errors: if !ok { errChan <- fmt.Errorf("文件监听错误通道已关闭") return } errChan <- err } } }
使用说明
- 安装依赖:运行前需要安装文件监听库,执行命令:
go get github.com/fsnotify/fsnotify - 替换路径:将代码中的
/path/to/your/target.txt替换为你实际要监听的文本文件路径 - 调整定时器:如果需要单次触发定时器,可将
time.NewTicker替换为time.After,并在处理后重新生成;若需要调整周期,修改10 * time.Second即可 - 测试信号:运行程序后,在另一个终端执行
kill -SIGUSR1 <进程ID>即可触发信号事件
关键细节
- 所有事件监听逻辑都在独立goroutine中执行,不会阻塞主循环
- 通过
select实现多路IO复用,确保各类事件都能被及时响应 - 加入了错误处理通道,避免监听过程中的错误被静默忽略
- 文件监听可通过
fsnotify.Event.Has()过滤特定操作类型(如写入、创建、删除等)
内容的提问来源于stack exchange,提问作者TrailSurfer
相关产品推荐
相关产品推荐

