You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
		}
	}
}

使用说明

  1. 安装依赖:运行前需要安装文件监听库,执行命令:go get github.com/fsnotify/fsnotify
  2. 替换路径:将代码中的/path/to/your/target.txt替换为你实际要监听的文本文件路径
  3. 调整定时器:如果需要单次触发定时器,可将time.NewTicker替换为time.After,并在处理后重新生成;若需要调整周期,修改10 * time.Second即可
  4. 测试信号:运行程序后,在另一个终端执行kill -SIGUSR1 <进程ID>即可触发信号事件

关键细节

  • 所有事件监听逻辑都在独立goroutine中执行,不会阻塞主循环
  • 通过select实现多路IO复用,确保各类事件都能被及时响应
  • 加入了错误处理通道,避免监听过程中的错误被静默忽略
  • 文件监听可通过fsnotify.Event.Has()过滤特定操作类型(如写入、创建、删除等)

内容的提问来源于stack exchange,提问作者TrailSurfer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 07:12:40