এই অজগর স্ক্রিপ্টটি কেন 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()

এটি প্রত্যাশার মতো কাজ করছে তবে এটি খুব বেশি সিপিইউ (100% সিপিইউ) খায়।

আমি কীভাবে এত বেশি খরচ না করে এটি সঠিকভাবে কাজ করতে পারি?


26
আপনি যদি যে ফ্রেমওয়ার্কটি ব্যবহার করছেন তা যদি সমর্থিত হয় তবে লুপের পরিবর্তে ক্লিপবোর্ডে পরিবর্তনগুলি সনাক্ত করতে ইভেন্ট-ভিত্তিক কোডটি ব্যবহার করুন। ক্লিপবোর্ডটি পরিবর্তন না হওয়া অবধি অবিচ্ছিন্নভাবে পাওয়া বা সিস্টেমটি আপনাকে এটি পরিবর্তিত হয়েছে তা শোনার মধ্যে একটি পার্থক্য রয়েছে।
স্টিফান

6
@dessert আমি কখনো এটা পাইথন মধ্যে সম্পন্ন করেছেন, কিন্তু এখানে জিটিকে সঙ্গে একটি সমাধান হবে বলে মনে হয়: stackoverflow.com/a/25961646/985296 (যে কোন প্ল্যাটফর্ম নির্ভরতা উল্লেখ না)।
স্টিফান

@ jpmc26 & মিষ্টান্নটি একটি মেটা আলোচনার মতো মনে হচ্ছে, এটি সেখানে নিয়ে যেতে দ্বিধা বোধ করবেন। এটিকে সুযোগের জন্য পরিষ্কার করার জন্য অবশ্যই একটি ভাল ধারণা ।
মাস্তে

1
@ ডেজার্ট একটি মেটা থ্রেড খুলুন যদি আপনি এবং জেপিএমসি এই বিষয়ে / বন্ধ বিষয়টি নিয়ে আলোচনা করতে চান। দয়া করে এই যুক্তিটির জন্য মন্তব্যগুলি ব্যবহার করবেন না। (মন্তব্য সাফাই সম্পূর্ণ, আপনার মেটা আলোচনার জন্য মুলতুবি এক সপ্তাহের জন্য লক হয়েছে তবে মন্তব্যের যুক্তিও বন্ধ করতে পারে)
টমাস ওয়ার্ড

উত্তর:


44

আপনি time.sleep()নিজের whileলুপটি ভুলে গেছেন , এই উত্তর অনুসারে 0.2 এর জন্য ঘুমানো ভোটদানের ফ্রিকোয়েন্সি এবং সিপিইউ লোডের মধ্যে একটি ভাল সমঝোতা:

import time

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

প্রতি 0.2 সেকেন্ডে ক্লিপবোর্ড চেক করা প্রায়শই সহজেই যথেষ্ট মনে হয়; আপনি যদি কম সিপিইউ লোড চান তবে আপনি এই মানটিও বাড়িয়ে তুলতে পারেন - কয়েক জন ব্যবহারকারী ক্লিপবোর্ড সামগ্রীটি এক সেকেন্ড থেকে অন্য সেকেন্ডে পরিবর্তন করে।

নোট করুন যে কোনও লুপে সাধারণ ভোটদানের ক্ষেত্রে যত তাড়াতাড়ি ভাল ডিজাইন হিসাবে বিবেচিত হয় না। ক্লিপবোর্ডের বিষয়বস্তু পরিবর্তন করার ঘটনায় কাজ করা আরও ভাল উপায় হবে , জিটিকে-র একটি উদাহরণ এই এসও উত্তরে পাওয়া যাবে ।

আরও পড়া


3
আপনি ব্যবহৃত সিপিইউ সময়কে প্রকৃতপক্ষে প্রভাবিত না করেই ঘুমের ব্যবধানকে আরও খাটো করে তুলতে পারেন। আমি আমার ম্যাকটিতে পেয়েছি: 0.01 s: 69%, 0.02 s: 43%, 0.05 s: 25%, 0.1 s: 14%, 0.2 s: 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

এটির জন্য জর্জের xclipপ্যাকেজ দরকার:

sudo apt install xclip

এটি catকমান্ডটি ব্যবহার করে ক্লিপবোর্ডের সামগ্রীগুলি স্ক্রিনে ফেলে দিচ্ছে । আপনি হার্ড কপি চান পরিবর্তে প্রতিস্থাপন catসঙ্গে lpএবং আপনার মুদ্রকের নাম, অভিযোজন এবং সম্ভবত "পৃষ্ঠাটিতে হইয়া" বিকল্পটি উল্লেখ করুন।

কারণ আমি পছন্দ আপনি পর্দায় ল্যাগ একটি বিট দেখতে হবে sleep 1.0যতো তাড়াতাড়ি মানুষ হাইলাইট করতে পারেন টেক্সট এবং ব্যবহার যা প্রিন্টারের সঙ্গে কেউ খেয়াল করে হবে এবং এখনও Ctrl+ + C

আপনি যদি একই একই হাইলাইটেড পাঠ্যটি ক্লিপবোর্ডে অনুলিপি করেন তবে এটি কোনও তফাতকে ট্রিগার করে না। কম বেশি একটি চিঠি একটি প্রতিক্রিয়া ট্রিগার করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.