Почему этот скрипт Python работает в фоновом режиме и потребляет 100% ресурсов процессора?

Я хочу запустить простой 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()

Это работает, как и ожидалось, но потребляет слишком много ЦП (100% ЦП).

Как я могу заставить его работать правильно, не потребляя так много?

22
задан 18 May 2019 в 19:53

4 ответа

Вы забыли time.sleep() в Вашем while цикл, согласно этому ответу на НАСТОЛЬКО спящем в течение 0,2 с является хорошим компромиссом между частотой запросов и загрузкой ЦП:

import time

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

Проверка буфера обмена каждые 0.2 секунды кажется легко достаточно часто; если Вы хотите меньше загрузки ЦП, можно даже увеличить это значение – немного пользователей изменяют содержание буфера обмена с одной секунды другому.

Обратите внимание, что в общем опросе в цикле так же часто, как это не считают хорошим дизайном. Лучший подход должен был бы действовать на событие изменения содержания буфера обмена, пример для GTK может быть найден в этом, ТАК ответьте.

Дальнейшее чтение

44
ответ дан 18 May 2019 в 19:53

Я наконец заставил это работать без цикла. Это код:

Мне пришлось установить несколько модулей: 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()

не стесняйтесь выбирать решение, которое подходит именно вам.

0
ответ дан 18 May 2019 в 19:53

Вы запускаете вещь в цикле while True:! Это означает, что процессор постоянно выполняет ваш цикл. Просто добавьте небольшую паузу, и вы увидите, что загрузка процессора резко падает:

#!/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)
0
ответ дан 18 May 2019 в 19:53

Я был заинтригован этим проектом, поэтому написал сценарий 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

Для этого требуется пакет xclip Xorg:

sudo apt install xclip

Это выгрузка содержимого буфера обмена на экран с помощью команды cat. Если вы хотите получить печатную копию, замените cat на lp и укажите имя вашего принтера, ориентацию и, возможно, опцию «вписать в страницу».

Вы увидите некоторое отставание от экрана, потому что я выбрал sleep 1.0, что было бы незаметно для принтера и все же быстрее, чем люди могут выделить текст и использовать Ctrl + C .

Если вы скопируете точно такой же выделенный текст в буфер обмена, это не вызовет разницы. Одна буква более или менее вызовет ответ.

0
ответ дан 18 May 2019 в 19:53

Другие вопросы по тегам:

Похожие вопросы: