tutorial - python w3schools




পাইথন মধ্যে পর্যায়ক্রমিক কর্ম সঞ্চালন (6)

এই প্রশ্নটি ইতিমধ্যে একটি উত্তর আছে:

আমি উইন্ডোজ কাজ করছি। আমি একটি ফাংশন foo () প্রতি 10 সেকেন্ড সঞ্চালন করতে চান।

আমি এটা কিভাবে করবো?


আপনি একটি পৃথক থ্রেড আপনার টাস্ক সম্পাদন করতে পারেন। threading.Timer আপনাকে কিছু সময় পেরিয়ে যাওয়ার পরে একবার প্রদত্ত কলব্যাকটি কার্যকর করতে দেয়, যদি আপনি আপনার কাজটি চালাতে চান তবে উদাহরণস্বরূপ, যতক্ষণ glib.timeout_add True ফেরত দেয় (এটি আসলে glib.timeout_add প্রদান করে তবে আপনার হয়তো এটি উইন্ডোজ ইনস্টল করা আছে) অথবা আপনি এটি বাতিল না হওয়া পর্যন্ত, আপনি এই কোডটি ব্যবহার করতে পারেন:

import logging, threading, functools
import time

logging.basicConfig(level=logging.NOTSET,
                    format='%(threadName)s %(message)s')

class PeriodicTimer(object):
    def __init__(self, interval, callback):
        self.interval = interval

        @functools.wraps(callback)
        def wrapper(*args, **kwargs):
            result = callback(*args, **kwargs)
            if result:
                self.thread = threading.Timer(self.interval,
                                              self.callback)
                self.thread.start()

        self.callback = wrapper

    def start(self):
        self.thread = threading.Timer(self.interval, self.callback)
        self.thread.start()

    def cancel(self):
        self.thread.cancel()


def foo():
    logging.info('Doing some work...')
    return True

timer = PeriodicTimer(1, foo)
timer.start()

for i in range(2):
    time.sleep(2)
    logging.info('Doing some other work...')

timer.cancel()

উদাহরণ আউটপুট:

Thread-1 Doing some work...
Thread-2 Doing some work...
MainThread Doing some other work...
Thread-3 Doing some work...
Thread-4 Doing some work...
MainThread Doing some other work...

দ্রষ্টব্য: কলব্যাক প্রতিটি অন্তর্বর্তীকালীন মৃত্যুদন্ড কার্যকর করা হয় না। ব্যবধান হল কলব্যাকের মধ্যে শেষ সময় শেষ হওয়ার সময় এবং পরের বার বলা হয়।


আপনি যদি প্রতি 10 সেকেন্ডে একটি পাইথন স্ক্রিপ্টের ভিতরে foo () চালাতে চান তবে আপনি এই লাইনগুলিতে কিছু করতে পারেন।

import time

def foo():
    print "Howdy"

while True:
    foo()
    time.sleep(10)

এখানে থ্রেড ক্লাস ব্যবহার করে একটি চমৎকার বাস্তবায়ন: http://g-off.net/software/a-python-repeatable-threadingtimer-class

নীচের কোডটি একটু বেশি দ্রুত এবং নোংরা:

from threading import Timer
from time import sleep

def hello():
    print "hello, world"
    t = Timer(3,hello)
    t.start()

t = Timer(3, hello)
t.start() # after 3 seconds, "hello, world" will be printed

# timer will wake up ever 3 seconds, while we do something else
while True:
    print "do something else"
    sleep(10)

এটি foo() থেকে প্রতিটি কলের মধ্যে একটি 10 ​​সেকেন্ড ঘুম সন্নিবেশ করবে, যা কলটি দ্রুত শেষ হওয়ার জন্য আপনি যা জিজ্ঞেস করেছিলেন তা প্রায়।

import time
while True:
  foo()
  time.sleep(10)

সম্পাদনা: অন্য জিনিসগুলি করার জন্য যখন আপনার foo() একটি পটভূমি থ্রেডে বলা হচ্ছে

import time
import sys
import threading

def foo():
  sys.stdout.write('({}) foo\n'.format(time.ctime()))

def foo_target():
  while True:
    foo()
    time.sleep(10)

t = threading.Thread(target=foo_target)
t.daemon = True
t.start()
raw_input('do other things...')

শুধু 10 সেকেন্ডের জন্য বা threading.Timer(10,foo) ব্যবহার করে ঘুমানো। threading.Timer(10,foo) শুরু সময় ড্রিফট হতে হবে। (আপনি এটি সম্পর্কে চিন্তা নাও করতে পারেন, অথবা এটি আপনার সঠিক পরিস্থিতির উপর নির্ভর করে সমস্যার একটি উল্লেখযোগ্য উত্স হতে পারে।) এর জন্য দুটি কারণ হতে পারে - আপনার থ্রেডের জেগে উঠার সময়ে ত্রুটিগুলি বা আপনার ফাংশনের জন্য কার্যকর সময়।

আপনি এই পোস্টের শেষে কিছু ফলাফল দেখতে পারেন তবে প্রথমে এটি কীভাবে সমাধান করবেন তার একটি উদাহরণ। যখন আপনার ফাংশনটিকে পরবর্তীতে বলা হয়ে থাকে তখন এটি আপনাকে ট্র্যাক করতে হবে এবং পার্থক্যের জন্য অ্যাকাউন্টটি যখন বলা হয়ে থাকে তখন তার বিরোধিতা করা উচিত।

এখানে একটি সংস্করণ যা সামান্য drifts:

import datetime, threading

def foo():
    print datetime.datetime.now()
    threading.Timer(1, foo).start()

foo()

এর আউটপুট এই মত দেখাচ্ছে:

2013-08-12 13:05:36.483580
2013-08-12 13:05:37.484931
2013-08-12 13:05:38.485505
2013-08-12 13:05:39.486945
2013-08-12 13:05:40.488386
2013-08-12 13:05:41.489819
2013-08-12 13:05:42.491202
2013-08-12 13:05:43.492486
2013-08-12 13:05:44.493865
2013-08-12 13:05:45.494987
2013-08-12 13:05:46.496479
2013-08-12 13:05:47.497824
2013-08-12 13:05:48.499286
2013-08-12 13:05:49.500232

আপনি দেখতে পারেন যে সাব-সেকেন্ড কাউন্ট ক্রমাগত বৃদ্ধি পাচ্ছে এবং এইভাবে, শুরু করার সময়টি "ড্রিফটিং"।

এই কোডটি সঠিকভাবে ড্রিফটয়ের জন্য অ্যাকাউন্ট:

import datetime, threading, time

next_call = time.time()

def foo():
  global next_call
  print datetime.datetime.now()
  next_call = next_call+1
  threading.Timer( next_call - time.time(), foo ).start()

foo()

এর আউটপুট এই মত দেখাচ্ছে:

2013-08-12 13:21:45.292565
2013-08-12 13:21:47.293000
2013-08-12 13:21:48.293939
2013-08-12 13:21:49.293327
2013-08-12 13:21:50.293883
2013-08-12 13:21:51.293070
2013-08-12 13:21:52.293393

এখানে আপনি দেখতে পারেন যে উপ-দ্বিতীয় বার কোন বৃদ্ধি নেই।

আপনার ইভেন্টগুলি যদি সত্যিই ঘন ঘন ঘটছে তবে প্রতিটি ইভেন্টের জন্য একটি নতুন থ্রেড শুরু করার পরিবর্তে আপনি একক থ্রেডে টাইমারটি চালাতে পারেন। ড্রিফট জন্য অ্যাকাউন্টিং যখন এই মত হবে:

import datetime, threading, time

def foo():
    next_call = time.time()
    while True:
        print datetime.datetime.now()
        next_call = next_call+1;
        time.sleep(next_call - time.time())

timerThread = threading.Thread(target=foo)
timerThread.start()

তবে আপনার অ্যাপ্লিকেশনটি সাধারণত প্রস্থান করবে না, আপনাকে টাইমার থ্রেডটি খুন করতে হবে। আপনার আবেদনটি সম্পন্ন করার পরে আপনি সাধারণত প্রস্থান করতে চান, নিজে নিজে থ্রেডটি খোলার পরে, আপনাকে ব্যবহার করতে হবে

timerThread = threading.Thread(target=foo)
timerThread.daemon = True
timerThread.start()





python