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

在Go语言中使用gohook监听键盘事件的同时执行循环任务的实现方案

在Go语言中使用gohook监听键盘事件的同时执行循环任务的实现方案

嘿,我完全懂你的困扰!之前用gohook的示例代码时,监听键盘的操作会把整个程序卡住,没法同时跑其他任务——这其实就是没用到Go的协程(goroutine)而已,咱们调整一下就能解决~

gohook的hook.Start()方法是阻塞式的,它会一直占用当前goroutine来监听事件。所以咱们只需要把监听逻辑放到一个单独的goroutine里,这样主goroutine(或者另一个协程)就能同时执行你的循环任务了。另外,咱们还得加个退出机制,不然程序没法优雅停止,比如监听某个特定按键(比如Esc)来触发退出,同时终止循环任务。

下面是完整的实现代码:

package main

import (
	"fmt"
	"os"
	"time"

	hook "github.com/robotn/gohook"
)

func main() {
	// 创建一个通道,用来传递退出信号
	exitChan := make(chan struct{})

	// 启动一个goroutine来监听键盘事件
	go func() {
		// 注册键盘事件监听,这里可以改成你需要的特定按键
		evChan := hook.Start()
		defer hook.End() // 确保退出时清理hook资源

		for ev := range evChan {
			// 检测是否按下Esc键(键码是27),触发退出
			if ev.Kind == hook.KeyDown && ev.Keychar == 27 {
				fmt.Println("\n收到退出信号,正在停止程序...")
				close(exitChan)
				return
			}

			// 这里可以处理你需要监听的特定按键逻辑
			if ev.Kind == hook.KeyDown {
				fmt.Printf("按下了按键: %c (键码: %d)\n", ev.Keychar, ev.Keycode)
			}
		}
	}()

	// 主goroutine执行循环任务
	fmt.Println("循环任务开始运行,按Esc键退出...")
loop:
	for {
		select {
		case <-exitChan:
			break loop // 收到退出信号,终止循环
		default:
			// 这里写你的循环任务逻辑,比如打印当前时间
			fmt.Printf("当前时间: %s\n", time.Now().Format("2006-01-02 15:04:05"))
			time.Sleep(1 * time.Second) // 模拟任务耗时
		}
	}

	fmt.Println("程序已退出")
}

代码关键点说明:

  • 用go func() {...}()把监听逻辑包装成一个协程,这样它就不会阻塞主程序的执行了。
  • exitChan是一个无缓冲通道,用来在监听协程和主协程之间传递退出信号,确保两者能同步停止。
  • select语句让循环任务既能持续执行,又能随时响应退出信号,不会一直卡在循环里没法停止。
  • defer hook.End()很重要,它会在监听协程退出时自动清理gohook的资源,避免内存泄漏。

小提示:

如果你需要监听多个特定按键,只需要在for ev := range evChan的循环里增加对应的判断条件就行。另外,如果你的循环任务涉及到共享资源,记得用sync.Mutex来做并发安全保护,避免出现竞态问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:48:15