اذهب إلى المحتوى

السؤال

نشر

أريد أن أقوم باستدعاء دالة ما وبدء عداد counter وإذا وصل العداد إلى 10 ثوان ولم تنتهي الدالة بعد يتم إيقاف الدالة على الفور (حتى وإن لم تقم بعمل return )

أي كيف أقوم بعمل TimeOut لدالة ما في بايثون؟

Recommended Posts

  • 0
نشر

بإمكانك إستخدام مكتبة تدعي signal  هذه المكتبة تقوم بتتبع دالة معينة و من ثم توقيفها او عمل أي شيئ أخر بعد مرور وقت معين انت تقوم بتعريفه لها التالي طريقة خلق صنف قائم على هذه المكتبة و المثال الذي يليه سيكون كيفية أستخدام هذا الصنف 

from functools import wraps
import errno
import os
import signal

#هنا نعرف الصنف و هو يرث من Exeptions
class TimeoutError(Exception):
    pass

  #هنا نعرف الدالة الني سنقوم بأستخدامها لتقفي الوقت و أنهاء أي دالة تقوم انت تريده يعد هذا الوقت 
def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
  #هنا نعرف المزين 
    def decorator(func):
      #داخل المزين نقوم بتعريف الدوال التي تقوم بالتعرف على الدوال الخارجية و كيفية التعامل معها 
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)

        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return wraps(func)(wrapper)

    return decorator

هنا سنقوم بإستخدام هذا الصنف لايقاف دالة بعد فترة من الوقت كالتالي :

from timeout import timeout

# مهلة وظيفة تشغيل طويلة مع انتهاء صلاحية افتراضي يبلغ 10 ثوانٍ.
@timeout
def long_running_function1():
    ...

# مهلة بعد 5 ثوان
@timeout(5)
def long_running_function2():
    ...

# انتهت المهلة بعد 30 ثانية ، مع ظهور الخطأ "انتهت مهلة الاتصال"
@timeout(30, os.strerror(errno.ETIMEDOUT))
def long_running_function3():

 

  • 1
نشر

يمكنك أيضاً استخدام ال multiprocessing.Process لعمل المطلوب كالتالي

import multiprocessing
import time

# bar
def bar():
    for i in range(100):
        print "Tick"
        time.sleep(1)

if __name__ == '__main__':
    # process نقوم بتنفيذ الدالة ك
    p = multiprocessing.Process(target=bar)
    p.start()

    # الإنتظار ل 10 ثواني
    p.join(10)

    # مازالت تعمل process  التحقق إذا كانت ال
    if p.is_alive():
        print "running... let's kill it..."

        # إيقاف الدالة
        p.terminate()
        #أيضاً kill يمكن إيقاف الدالةعن طريق 
        # p.kill()

        p.join()
  • 0
نشر

في البرمجة عند القيام بإستدعاء دالة أو إيقاف دالة بناءً على وقت محدد لدالة سابقة يسمى بإنتهاء المهلة TimeOut أي عند إنتهاء المهلة المحددة لدالةً ما سواءً انتهت من عملها أم لم تنتهي سيتم إستدعاء دالة أخرى أو إيقاف هذه الدالة

في بايثون هناك عدة طرق لعمل ذلك ، مثل إستخدام subprocess كالآتي

import subprocess
r = subprocess.run(['echo', 'hello timeout'], timeout=5) # اسم البرنامج ثم كتابة خيار إذا وجد وثم الوقت المحدد
print(
    f'''type(r)={type(r)}, 
    r.args={r.args}, 
    r.returncode={r.returncode}, 
    r.stdout={r.stdout}, 
    r.stderr={r.stderr}'''
)
# نقوم بتجربة اتصال لموقع قوقل خلال 5 ثواني
# فإذا انتهت الفترة نقوم بطابعة ان مهلة الوقت قد انتهت
try:
    r = subprocess.run(['ping', 'www.google.com'], timeout=5)
except subprocess.TimeoutExpired as e:
    print(e)

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...