यह अजगर स्क्रिप्ट क्यों 100% सीपीयू की पृष्ठभूमि में चल रहा है?


22

मैं पृष्ठभूमि में एक सरल अजगर स्क्रिप्ट चलाना चाहता हूं जो क्लिपबोर्ड से पाठ पढ़ता है और इसे प्रिंट करता है। यहाँ मेरा कोड है।

#!/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) की खपत करता है।

मैं इतना उपभोग किए बिना इसे सही ढंग से कैसे काम कर सकता हूं?


26
यदि आपके द्वारा उपयोग किए जा रहे फ्रेमवर्क द्वारा समर्थित है, तो एक लूप के बजाय क्लिपबोर्ड में परिवर्तन का पता लगाने के लिए इवेंट-आधारित कोड का उपयोग करें। क्लिपबोर्ड को लगातार बदलने और इसे बदलने वाले सिस्टम को सुनने के लिए आपके बीच अंतर होने के बीच अंतर होता है।
स्टीफन

6
@ डेज़र्ट मैंने कभी अजगर में नहीं किया है, लेकिन यहाँ GTK: stackoverflow.com/a/25961646/985296 (किसी भी प्लेटफ़ॉर्म निर्भरता का उल्लेख नहीं है) के साथ एक समाधान प्रतीत होता है।
स्टीफन

@ jpmc26 और मिठाई एक मेटा चर्चा की तरह लग रहा है, वहाँ इसे लेने के लिए स्वतंत्र महसूस हो रहा है। निश्चित रूप से एक अच्छा विचार है कि इस दायरे के लिए मंजूरी दे दी है ।
मस्त

1
@dessert एक मेटा थ्रेड खोलें यदि आप और JPMC चर्चा करना चाहते हैं कि क्या यह विषय चालू है। कृपया इस तर्क के लिए टिप्पणियों का उपयोग न करें। (टिप्पणी सफाई पूर्ण, एक सप्ताह के लिए बंद विषय आपकी मेटा चर्चा लंबित लेकिन यह भी टिप्पणी तर्क बंद करने के लिए)
थॉमस वार्ड :

जवाबों:


44

आप time.sleep()अपने whileपाश में भूल गए , 0.2 के लिए सो सो पर इस जवाब के अनुसार मतदान आवृत्ति और सीपीयू लोड के बीच एक अच्छा समझौता है:

import time

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

क्लिपबोर्ड की जांच हर 0.2 सेकंड में आसानी से अक्सर पर्याप्त लगती है; यदि आप कम सीपीयू लोड चाहते हैं, तो आप इस मूल्य को भी बढ़ा सकते हैं - कुछ उपयोगकर्ता क्लिपबोर्ड सामग्री को एक सेकंड से दूसरे में बदलते हैं।

ध्यान दें कि एक लूप में सामान्य मतदान में अक्सर उतना ही अच्छा डिज़ाइन नहीं माना जाता है। क्लिपबोर्ड सामग्री को बदलने की घटना पर कार्य करने के लिए एक बेहतर तरीका होगा , इस SO उत्तर में GTK के लिए एक उदाहरण मिल सकता है ।

आगे की पढाई


3
आप वास्तव में उपयोग किए गए सीपीयू समय को प्रभावित किए बिना नींद के अंतराल को कम कर सकते हैं। मैंने अपने मैक पर पाया: 0.01 एस: 69%, 0.02 एस: 43%, 0.05 एस: 25%, 0.1 एस: 14%, 0.2 एस: 7%। 0.5 एस: 3%
फ्लोरिस

6
मतदान अभी भी बेकार है क्योंकि यह इस प्रक्रिया को सीपीयू कैश और इतने पर प्रदूषित करता है। क्लिपबोर्ड परिवर्तन की सूचना के लिए प्रतीक्षा करने के लिए टिप्पणियों में बेहतर तरीके से चर्चा की गई
पीटर कॉर्डेस

@ डर्टर्ट: अगर मुझे जवाब पता होता तो मैं करता। मैं केवल आपके उत्तर में उल्लेख करने का सुझाव देता हूं कि प्रत्येक 0.2 सेकंड में जागने को अभी भी एक अच्छा डिजाइन नहीं माना जाता है , और गैर-मतदान दृष्टिकोण की तलाश करना बेहतर होगा। लेकिन एक-बंद हैक के लिए जो केवल एक कंप्यूटर पर चलने वाला है, यकीन है कि यह भयानक नहीं है, और शायद काफी अच्छा है।
पीटर कॉर्डेस

26

मैं अंत में इसे बिना लूप के काम करता हूं। यह कोड है:

मुझे कुछ मॉड्यूल स्थापित करने थे: 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()

आपके लिए उपयुक्त समाधान का चयन करने के लिए स्वतंत्र महसूस करें।


ऊह ... आप clip.wait_for_text()दो बार क्यों अनुरोध कर रहे हैं ?
wizzwizz4

@ wizzwizz4 तुम सही हो मैं संपादित ... टैंक
dmx

@ wizzwizz4 क्या हर कोई सिर्फ सुनिश्चित होने के लिए दो बार कॉपी नहीं करता है?
माइकल फ्रैंक

16

आप बात को 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)

3

मैं इस परियोजना से बहुत प्रभावित था, इसलिए उस वातावरण में उन लोगों के लिए एक बैश स्क्रिप्ट लिखी:

#!/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कमांड का उपयोग करके स्क्रीन पर क्लिपबोर्ड सामग्री डंप कर रहा है । आप हार्ड कॉपी चाहते हैं बजाय की जगह catके साथ lpऔर अपने प्रिंटर का नाम, अभिविन्यास और संभवतः "पेज के लिए फिट" विकल्प निर्दिष्ट करें।

आपको स्क्रीन पर थोड़ा सा अंतराल दिखाई देगा क्योंकि मैं चुनता हूं sleep 1.0जो एक प्रिंटर के साथ ध्यान देने योग्य होगा और अभी भी लोगों की तुलना में तेजी से पाठ को उजागर कर सकता है और Ctrl+ का उपयोग कर सकता है C

यदि आप उसी हाइलाइट किए गए टेक्स्ट को क्लिपबोर्ड पर कॉपी करते हैं तो इससे अंतर नहीं होता है। एक या अधिक अक्षर कम प्रतिक्रिया को ट्रिगर करेंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.