为什么这个在后台运行的 Python 脚本会消耗 100% 的 CPU?

为什么这个在后台运行的 Python 脚本会消耗 100% 的 CPU?

我想在后台运行一个简单的 Python 脚本,从剪贴板读取文本并将其打印出来。这是我的代码。

#!/usr/bin/env python

import Tkinter

last_clipboard = ""

def get_clipboard():
  global last_clipboard
  root = Tkinter.Tk()
  root.withdraw() # Hide the main window (optional)
  text_in_clipboard = root.clipboard_get()
  if text_in_clipboard != last_clipboard:
    last_clipboard = text_in_clipboard
    print last_clipboard


while True:
  get_clipboard()

这可以按预期工作,但是它消耗了太多 CPU(100% CPU)。

我怎样才能让它正常工作而又不消耗那么多?

答案1

你忘记了time.sleep()在你的while循环中,根据这个答案休眠 0.2 秒是轮询频率和 CPU 负载之间的一个很好的折衷:

import time

while True:
  get_clipboard()
  time.sleep(0.2) # sleep for 0.2 seconds

每 0.2 秒检查一次剪贴板似乎足够频繁;如果您希望减少 CPU 负载,甚至可以增加此值——很少有用户会在一秒钟内更改剪贴板内容。

请注意,通常,如此频繁地循环轮询并不是好的设计。更好的方法是根据事件更改剪贴板内容,可以找到 GTK 的示例在这个SO答案中

进一步阅读

答案2

我最终让它不循环地工作。这是代码:

我必须安装几个模块:sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0

#!/usr/bin/env python3
import gi, sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk

last_clipboard = ""

def callBack(*args):
  global last_clipboard
  new_clipboard = clip.wait_for_text()
  if new_clipboard != last_clipboard:
    last_clipboard = new_clipboard
    print("new Clipboard")
    print(new_clipboard)

clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clip.connect('owner-change',callBack)
Gtk.main()

请随意选择适合您的解决方案。

答案3

你正在循环运行这个程序while True:!这意味着 CPU不断地运行你的循环。只需在那里暂停一下,你就会看到 CPU 使用率急剧下降:

#!/usr/bin/env python

import Tkinter
import time

last_clipboard = ""

def get_clipboard():
  global last_clipboard
  root = Tkinter.Tk()
  root.withdraw() # Hide the main window (optional)
  text_in_clipboard = root.clipboard_get()
  if text_in_clipboard != last_clipboard:
    last_clipboard = text_in_clipboard
    print last_clipboard

while True:
  get_clipboard()
  time.sleep(1)

答案4

我对这个项目很感兴趣,所以为那些更适合该环境的人编写了一个 bash 脚本:

#!/bin/bash

xclip -o -sel clip > /tmp/LastClip

while true ; do 

    xclip -o -sel clip > /tmp/NewClip
    diff -q /tmp/LastClip /tmp/NewClip > /tmp/DiffClip
    if [[ -s /tmp/DiffClip ]] ; then
        cat /tmp/NewClip    # For testing dump to screen instead of printing
        cp -a /tmp/NewClip /tmp/LastClip
    fi
    sleep 1.0

done

它确实需要 Xorg 的xclip包:

sudo apt install xclip

它使用cat命令将剪贴板内容转储到屏幕上。如果您想要硬拷贝,请替换catlp并指定您的打印机名称、方向以及可能的“适合页面”选项。

您会看到屏幕有点滞后,因为我选择了sleep 1.0使用打印机无法察觉的延迟,但仍然比人们突出显示文本和使用Ctrl+更快C

如果您将完全相同的突出显示文本复制到剪贴板,则不会触发差异。多一个字母或少一个字母都会触发响应。

相关内容