পাইথনটি পাইথনের মাল্টিপ্রসেসিং পুলের সাথে বাধা দেয়


136

পাইথনের মাল্টিপ্রসেসিং পুলগুলির সাহায্যে কী-বোর্ড ইন্টারটার্ট ইভেন্টগুলি কীভাবে আমি পরিচালনা করতে পারি? এখানে একটি সহজ উদাহরণ:

from multiprocessing import Pool
from time import sleep
from sys import exit

def slowly_square(i):
    sleep(1)
    return i*i

def go():
    pool = Pool(8)
    try:
        results = pool.map(slowly_square, range(40))
    except KeyboardInterrupt:
        # **** THIS PART NEVER EXECUTES. ****
        pool.terminate()
        print "You cancelled the program!"
        sys.exit(1)
    print "\nFinally, here are the results: ", results

if __name__ == "__main__":
    go()

উপরের কোডটি চালানোর KeyboardInterruptসময়, আমি টিপানোর সময় উত্থাপিত হয় ^C, তবে প্রক্রিয়াটি কেবল সেই সময়ে স্তব্ধ হয় এবং আমাকে এটি বাহ্যিকভাবে হত্যা করতে হয়।

আমি যে ^Cকোনও সময় টিপতে সক্ষম হতে চাই এবং সমস্ত প্রক্রিয়াটি নিখুঁতভাবে প্রস্থান করতে চাই।


আমি psutil ব্যবহার করে আমার সমস্যার সমাধান, আপনাকে সমাধান এখানে দেখতে পারেন: stackoverflow.com/questions/32160054/...
টিয়াগো Albineli আইনজীবীরা Motta

উত্তর:


137

এটি পাইথন বাগ। থ্রেডিংয়ে শর্তের জন্য অপেক্ষা করার সময় ond কন্ডিশন.ওয়েট () কখনই কীবোর্ডইন্টারট্রপ পাঠানো হয় না। Repro:

import threading
cond = threading.Condition(threading.Lock())
cond.acquire()
cond.wait(None)
print "done"

অপেক্ষা () প্রত্যাবর্তন না হওয়া অবধি কীবোর্ড আন্তঃবিধ ব্যতিক্রম সরবরাহ করা হবে না এবং এটি কখনই ফিরে আসে না, যাতে বাধা কখনই ঘটে না। কীবোর্ড ইন্টারটারপ্ট অবশ্যই একটি শর্ত অপেক্ষা করতে বাধা উচিত।

নোট করুন যে একটি সময়সীমা নির্দিষ্ট করা থাকলে এটি ঘটে না; cond.wait (1) অবিলম্বে বাধা প্রাপ্ত করবে। সুতরাং, একটি সময়সীমা নির্দিষ্ট করা একটি workaround হয়। এটি করতে, প্রতিস্থাপন করুন

    results = pool.map(slowly_square, range(40))

সঙ্গে

    results = pool.map_async(slowly_square, range(40)).get(9999999)

অথবা সাদৃশ্যপূর্ণ.


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

18
এই বাগটি [ইস্যু 8296] [1] হিসাবে দায়ের করা হয়েছে। [1]: বাগস.পিথন.আর.উইসু 8296
আন্দ্রে ভ্লাসভস্কিখ

1
এখানে একটি হ্যাক রয়েছে যা একইভাবে পুল.আইএমপ () ঠিক করে, ইমপ্যাকটি পুনরাবৃত্তি করার সময় Ctrl-C সম্ভব করে তোলে। ব্যতিক্রমটি ধরুন এবং কল পুল.টার্মিনেট () কল করুন এবং আপনার প্রোগ্রামটি প্রস্থান করবে। gist.github.com/626518
আলেকজান্ডার

6
এটি জিনিসগুলিকে পুরোপুরি ঠিক করে না। আমি যখন কন্ট্রোল + সি টিপতাম তখন কখনও কখনও আমি প্রত্যাশিত আচরণ পাই other আমি কেন নিশ্চিত তা না, তবে দেখে মনে হচ্ছে সম্ভবত কীবোর্ড ইন্টারটার্পট এলোমেলোভাবে একটি প্রক্রিয়া দ্বারা গ্রহণ করা হয়েছে, এবং পিতামাতার প্রক্রিয়াটি এটি ধরলে আমি কেবল সঠিক আচরণটি পাই।
রায়ান সি। থম্পসন

6
উইন্ডোজটিতে পাইথন ৩.6.১ নিয়ে এটি আমার পক্ষে কাজ করে না। আমি যখন Ctrl-C করি, তখন আমি প্রচুর স্ট্যাকের চিহ্ন এবং অন্যান্য আবর্জনা পাই get আসলে আমি এই থ্রেড থেকে চেষ্টা করেছি এমন কোনও সমাধানই কাজ করছে বলে মনে হচ্ছে না ...
সমাধানই szx

56

আমি সম্প্রতি যা পেয়েছি তা থেকে, সমাধানটি পুরোপুরি উপেক্ষা করার জন্য কর্মী প্রক্রিয়াগুলি সেট আপ করা এবং সমস্ত ক্লিনআপ কোডটি প্যারেন্ট প্রসেসে সীমাবদ্ধ করার সর্বোত্তম সমাধান। এটি অলস এবং ব্যস্ত কর্মী উভয় প্রক্রিয়ার জন্যই সমস্যার সমাধান করে এবং আপনার সন্তানের প্রক্রিয়াগুলিতে কোনও ত্রুটি পরিচালনা করার কোডের প্রয়োজন নেই।

import signal

...

def init_worker():
    signal.signal(signal.SIGINT, signal.SIG_IGN)

...

def main()
    pool = multiprocessing.Pool(size, init_worker)

    ...

    except KeyboardInterrupt:
        pool.terminate()
        pool.join()

ব্যাখ্যা এবং সম্পূর্ণ উদাহরণ কোডটি যথাক্রমে http://noswap.com/blog/python-multprocessing-keyboardinterrupt/ এবং http://github.com/jreese/m মাল্টিপ্রসেসিং- কীবোর্ডার ইন্টারপ্রেটে পাওয়া যাবে ।


4
হাই জন. আপনার সমাধানটি আমার, হ্যা দুর্ভাগ্যক্রমে জটিল, সমাধান হিসাবে একই জিনিসটি সম্পাদন করে না। এটি time.sleep(10)মূল প্রক্রিয়াটির পিছনে লুকায় । আপনি যদি সেই ঘুমটি সরিয়ে ফেলেন, বা আপনি যদি এই প্রক্রিয়াটি পুলটিতে যোগদানের চেষ্টা না করা পর্যন্ত অপেক্ষা করেন, কাজগুলি সম্পূর্ণ হওয়ার গ্যারান্টি দেওয়ার জন্য আপনাকে যা করতে হবে, তবে আপনি এখনও একই সমস্যায় ভুগছেন যা মূল প্রক্রিয়াটি নয় পোল joinঅপারেশনের অপেক্ষায় এটি কীবোর্ড ইন্টারটারপেট গ্রহণ করবে না ।
বিবি

উত্পাদনে আমি এই কোডটি কোথায় ব্যবহার করেছি সেই ক্ষেত্রে, টাইম.স্লিপ () একটি লুপের অংশ ছিল যা প্রতিটি সন্তানের প্রক্রিয়ার স্থিতি পরীক্ষা করে এবং প্রয়োজনে যদি বিলম্বের পরে নির্দিষ্ট প্রক্রিয়া পুনরায় আরম্ভ করে। () যোগদানের পরিবর্তে যা সমস্ত প্রক্রিয়া সম্পন্ন হওয়ার জন্য অপেক্ষা করবে, এটি পৃথকভাবে তাদের উপর পরীক্ষা করবে, এটি নিশ্চিত করে যে মাস্টার প্রক্রিয়াটি প্রতিক্রিয়াশীল থাকবে।
জন রিস

2
সুতরাং এটি আরও ব্যস্ত অপেক্ষা (সম্ভবত চেকগুলির মধ্যে ছোট ছোট ঘুমের সাথে) ছিল যা যোগদানের পরিবর্তে অন্য পদ্ধতির মাধ্যমে প্রক্রিয়া সম্পন্ন করার পক্ষে জরিপ করেছে? যদি এটি হয় তবে সম্ভবত এই কোডটি আপনার ব্লগ পোস্টে অন্তর্ভুক্ত করা ভাল তবে যেহেতু আপনি গ্যারান্টি দিতে পারেন যে সমস্ত কর্মী যোগদানের চেষ্টা করার আগে সম্পন্ন করেছেন।
বিবিউ

4
এটি কাজ করে না। কেবল বাচ্চাদেরই সিগন্যাল প্রেরণ করা হয়। পিতামাতারা কখনও তা পান না, তাই pool.terminate()কখনও মৃত্যুদন্ড কার্যকর করা হয় না। বাচ্চাদের সংকেত উপেক্ষা করার ফলে কিছুই সফল হয় না। @ গ্লেনের উত্তর সমস্যার সমাধান করে।
সেরিন

1
এর আমার সংস্করণটি gist.github.com/admackin/003dd646e5fadee8b8d6রয়েছে ; সেটিতে কল নেই .join()বিঘ্ন উপর ব্যতীত - এটা কেবল নিজে ফল পরীক্ষা করে .apply_async()ব্যবহার AsyncResult.ready()যদি এটি প্রস্তুত কিনা দেখতে, যার অর্থ আমরা পরিচ্ছন্নভাবে সমাপ্ত করেছি।
অ্যান্ডি ম্যাককিনলে

29

কিছু কারণে, কেবল বেস Exceptionশ্রেণীর উত্তরাধিকার সূত্রে প্রাপ্ত ব্যতিক্রমগুলি সাধারণত পরিচালনা করা হয়। কর্মপরিকল্পনা হিসাবে, আপনি উদাহরণ KeyboardInterruptহিসাবে পুনরায় বাড়াতে পারেন Exception:

from multiprocessing import Pool
import time

class KeyboardInterruptError(Exception): pass

def f(x):
    try:
        time.sleep(x)
        return x
    except KeyboardInterrupt:
        raise KeyboardInterruptError()

def main():
    p = Pool(processes=4)
    try:
        print 'starting the pool map'
        print p.map(f, range(10))
        p.close()
        print 'pool map complete'
    except KeyboardInterrupt:
        print 'got ^C while pool mapping, terminating the pool'
        p.terminate()
        print 'pool is terminated'
    except Exception, e:
        print 'got exception: %r, terminating the pool' % (e,)
        p.terminate()
        print 'pool is terminated'
    finally:
        print 'joining pool processes'
        p.join()
        print 'join complete'
    print 'the end'

if __name__ == '__main__':
    main()

সাধারণত আপনি নিম্নলিখিত আউটপুট পাবেন:

staring the pool map
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
pool map complete
joining pool processes
join complete
the end

আপনি যদি আঘাত করেন তবে আপনি ^Cপাবেন:

staring the pool map
got ^C while pool mapping, terminating the pool
pool is terminated
joining pool processes
join complete
the end

2
দেখে মনে হচ্ছে এটি কোনও সম্পূর্ণ সমাধান নয়। যদি কোনও তার নিজস্ব আইপিসি ডেটা এক্সচেঞ্জ করার KeyboardInterruptসময় উপস্থিত হয় তবে multiprocessingতা try..catchসক্রিয় হবে না (স্পষ্টতই)।
আন্দ্রে ভ্লাসোভস্কিখ

আপনি raise KeyboardInterruptErrorএকটি সঙ্গে প্রতিস্থাপন করতে পারে return। আপনার কেবলমাত্র নিশ্চিত করতে হবে যে কী-বোর্ড ইন্টারটারপ্ট পাওয়ার সাথে সাথে শিশু প্রক্রিয়াটি শেষ হবে। প্রত্যাবর্তন মানটি উপেক্ষা করা হবে বলে মনে হচ্ছে, mainতবুও কীবোর্ড আন্তঃবিধ প্রাপ্ত হয়েছে।
বার্নহার্ড

8

সাধারণত এই সহজ গঠন জন্য কাজ করে Ctrl- Cপুল করুন:

def signal_handle(_signal, frame):
    print "Stopping the Jobs."

signal.signal(signal.SIGINT, signal_handle)

যেমনটি কয়েকটি অনুরূপ পোস্টে বলা হয়েছিল:

পাইথনে কীবোর্ডিন্টারপ্রেট ক্যাপচার ব্যতীত চেষ্টা করুন


1
এটি প্রতিটি কর্মী প্রক্রিয়াতেও করাতে হবে এবং মাল্টিপ্রসেসিং লাইব্রেরিটি শুরু করার সময় কী-বোর্ড-ইন্টার্নটার্ট উত্থাপিত হলে এখনও ব্যর্থ হতে পারে।
মারিওভিলাস

7

ভোট দেওয়া উত্তর মূল সমস্যাটি মোকাবেলা করে না তবে একই রকম পার্শ্ব প্রতিক্রিয়া।

মাল্টিপ্রসেসিং লাইব্রেরির লেখক জেসি নোলার multiprocessing.Poolএকটি পুরানো ব্লগ পোস্ট ব্যবহার করার সময় কীভাবে সিটিআরএল + সি এর সাথে সঠিকভাবে ডিল করতে হয় তা ব্যাখ্যা করেছেন ।

import signal
from multiprocessing import Pool


def initializer():
    """Ignore CTRL+C in the worker process."""
    signal.signal(signal.SIGINT, signal.SIG_IGN)


pool = Pool(initializer=initializer)

try:
    pool.map(perform_download, dowloads)
except KeyboardInterrupt:
    pool.terminate()
    pool.join()

আমি খুঁজে পেয়েছি যে প্রসেসপুলএকসিকিউটারেরও একই সমস্যা রয়েছে। আমি os.setpgrp()যে
ফিক্সটি সন্ধান করতে পেরেছিলাম তা হ'ল

1
অবশ্যই, একমাত্র পার্থক্য হ'ল ProcessPoolExecutorইনিশিয়ালাইজার ফাংশন সমর্থন করে না। ইউনিক্সে, আপনি forkপুলটি তৈরি করার আগে সিগ্যান্ডলারকে মূল প্রক্রিয়াটি অক্ষম করে এবং পরে এটি পুনরায় সক্ষম করে কৌশলটি অর্জন করতে পারেন। ইন নুড়ি , আমি চুপ SIGINTডিফল্টরূপে শিশু প্রক্রিয়ার উপর। পাইথন পুলগুলির সাথে তারা একই রকম না করার কারণ সম্পর্কে আমি অবগত নই। শেষে, ব্যবহারকারী SIGINTযদি নিজের / নিজেকে ক্ষতি করতে চান তবে হ্যান্ডলারটি পুনরায় সেট করতে পারে।
noxdafox

এই সমাধানটি সিআরটিএল-সিটিকে মূল প্রক্রিয়াটিতে বাধা দেওয়া থেকে বিরত বলে মনে হচ্ছে।
পল দাম

1
আমি কেবল পাইথন 3.5 তে পরীক্ষা করেছি এবং এটি কাজ করে, আপনি পাইথনের কোন সংস্করণ ব্যবহার করছেন? কি ওএস?
noxdafox

5

মনে হচ্ছে দু'টি সমস্যা রয়েছে যা বিরক্তিকর অবস্থায় মাল্টিপ্রসেসিংয়ের সময় বিরক্তিকর। প্রথম (গ্লেন দ্বারা চিহ্নিত) হ'ল তাত্ক্ষণিক প্রতিক্রিয়া পাওয়ার জন্য আপনাকে map_asyncসময়সীমার সাথে ব্যবহার mapকরতে হবে (অর্থাত্, পুরো তালিকাটি প্রক্রিয়াকরণ শেষ করবেন না)। দ্বিতীয় (অ্যান্ড্রে দ্বারা চিহ্নিত) হ'ল মাল্টিপ্রসেসিং ব্যতিক্রমগুলি ধরা দেয় না যা Exception(যেমন, SystemExit) থেকে উত্তরাধিকারসূত্রে আসে না । সুতরাং এখানে আমার সমাধানটি যা এই দুটির সাথেই কাজ করে:

import sys
import functools
import traceback
import multiprocessing

def _poolFunctionWrapper(function, arg):
    """Run function under the pool

    Wrapper around function to catch exceptions that don't inherit from
    Exception (which aren't caught by multiprocessing, so that you end
    up hitting the timeout).
    """
    try:
        return function(arg)
    except:
        cls, exc, tb = sys.exc_info()
        if issubclass(cls, Exception):
            raise # No worries
        # Need to wrap the exception with something multiprocessing will recognise
        import traceback
        print "Unhandled exception %s (%s):\n%s" % (cls.__name__, exc, traceback.format_exc())
        raise Exception("Unhandled exception: %s (%s)" % (cls.__name__, exc))

def _runPool(pool, timeout, function, iterable):
    """Run the pool

    Wrapper around pool.map_async, to handle timeout.  This is required so as to
    trigger an immediate interrupt on the KeyboardInterrupt (Ctrl-C); see
    http://stackoverflow.com/questions/1408356/keyboard-interrupts-with-pythons-multiprocessing-pool

    Further wraps the function in _poolFunctionWrapper to catch exceptions
    that don't inherit from Exception.
    """
    return pool.map_async(functools.partial(_poolFunctionWrapper, function), iterable).get(timeout)

def myMap(function, iterable, numProcesses=1, timeout=9999):
    """Run the function on the iterable, optionally with multiprocessing"""
    if numProcesses > 1:
        pool = multiprocessing.Pool(processes=numProcesses, maxtasksperchild=1)
        mapFunc = functools.partial(_runPool, pool, timeout)
    else:
        pool = None
        mapFunc = map
    results = mapFunc(function, iterable)
    if pool is not None:
        pool.close()
        pool.join()
    return results

1
আমি কোনও পারফরম্যান্স পেনাল্টি লক্ষ্য করি নি, তবে আমার ক্ষেত্রে এটি functionমোটামুটি দীর্ঘকালীন (কয়েকশো সেকেন্ড)।
পল দাম

এটি আসলে আর হয় না, অন্তত আমার চোখ এবং অভিজ্ঞতা থেকে। আপনি যদি পৃথক শিশু প্রক্রিয়াগুলিতে কীবোর্ডের ব্যতিক্রমটি ধরেন এবং এটি আরও একবার মূল প্রক্রিয়ায় ধরেন, তবে আপনি ব্যবহার চালিয়ে যেতে পারেন mapএবং সব কিছু ভাল। @Linux Cli Aikনীচে একটি সমাধান সরবরাহ করে যা এই আচরণটি তৈরি করে। map_asyncমূল থ্রেড শিশু প্রক্রিয়াগুলি থেকে প্রাপ্ত ফলাফলের উপর নির্ভর করে যদি ব্যবহার করা সর্বদা পছন্দসই নয়।
কোড ডোগগো

4

আমি খুঁজে পেয়েছি, আপাতত সবচেয়ে ভাল সমাধান হ'ল মাল্টিপ্রসেসিং.পুল বৈশিষ্ট্যটি ব্যবহার না করে বরং নিজের পুলের কার্যকারিতা রোল করুন। আমি অ্যাপ্লিকেশন_সেস্কের মাধ্যমে ত্রুটিটি প্রদর্শন করার পাশাপাশি একটিভাবে পুলের কার্যকারিতাটি কীভাবে পুরোপুরি ব্যবহার করা এড়াতে হবে তার একটি উদাহরণ সরবরাহ করেছি।

http://www.bryceboe.com/2010/08/26/python-multiprocessing-and-keyboardinterrupt/


একটি যাদুমন্ত্র মত কাজ করে. এটি একটি পরিষ্কার সমাধান এবং কোনও ধরণের হ্যাক নয় (/ আমার মনে হয়) .btw, অন্যদের প্রস্তাবিত .get (99999) এর কৌশলটি পারফরম্যান্সকে খারাপভাবে আঘাত করে ts
ওয়াল্টার

টাইমআউট ব্যবহার করা থেকে আমি কোনও পারফরম্যান্সের জরিমানা লক্ষ্য করিনি, যদিও আমি 999999 এর পরিবর্তে 9999 ব্যবহার করেছি The ব্যতিক্রমটি যখন ব্যতিক্রম শ্রেণীর উত্তরাধিকারসূত্রে প্রাপ্ত না হয় তখন উত্থাপিত হয়: তারপরে আপনাকে সময়সীমা শেষ না হওয়া পর্যন্ত অপেক্ষা করতে হবে আঘাত। এর সমাধান হ'ল সমস্ত ব্যতিক্রম ধরা (আমার সমাধান দেখুন)।
পল দাম

1

আমি পাইথনের একজন নবাগত। আমি উত্তরের জন্য সর্বত্র খুঁজছিলাম এবং এটি এবং কয়েকটি অন্যান্য ব্লগ এবং ইউটিউব ভিডিওতে হোঁচট খাচ্ছি। আমি উপরে লেখকের কোডটি পেস্ট করার চেষ্টা করেছি এবং উইন্ডোজ 7 64৪- বিটে আমার অজগর ২.7.১৩ এ পুনরুত্পাদন করার চেষ্টা করেছি। এটি আমি যা অর্জন করতে চাই তার কাছাকাছি।

আমি আমার সন্তানের প্রক্রিয়াগুলি কন্ট্রোলসিকে উপেক্ষা করার জন্য এবং পিতামাতার প্রক্রিয়াটি সমাপ্ত করতে তৈরি করেছি। দেখে মনে হচ্ছে শিশু প্রক্রিয়াটি বাইপাস করা আমার পক্ষে এই সমস্যাটি এড়ায়।

#!/usr/bin/python

from multiprocessing import Pool
from time import sleep
from sys import exit


def slowly_square(i):
    try:
        print "<slowly_square> Sleeping and later running a square calculation..."
        sleep(1)
        return i * i
    except KeyboardInterrupt:
        print "<child processor> Don't care if you say CtrlC"
        pass


def go():
    pool = Pool(8)

    try:
        results = pool.map(slowly_square, range(40))
    except KeyboardInterrupt:
        pool.terminate()
        pool.close()
        print "You cancelled the program!"
        exit(1)
    print "Finally, here are the results", results


if __name__ == '__main__':
    go()

যে অংশটি শুরু হয় pool.terminate()তা কার্যকর হবে বলে মনে হয় না।


আমি ঠিক এটিও খুঁজে পেয়েছি! আমি সত্যই মনে করি এটি এই জাতীয় সমস্যার সবচেয়ে ভাল সমাধান solution গৃহীত সমাধানটি map_asyncব্যবহারকারীকে নিয়ে আসে, যা আমি বিশেষভাবে পছন্দ করি না। অনেক পরিস্থিতিতে, আমার মতো, মূল থ্রেডের পৃথক প্রক্রিয়াগুলি শেষ হওয়ার জন্য অপেক্ষা করা প্রয়োজন। এ কারণেই এর অন্যতম কারণ map!
কোড ডোগগো

1

আপনি পুলের অবজেক্টের এপ্লিক_অ্যাসেন্স পদ্ধতিটি ব্যবহার করে দেখতে পারেন:

import multiprocessing
import time
from datetime import datetime


def test_func(x):
    time.sleep(2)
    return x**2


def apply_multiprocessing(input_list, input_function):
    pool_size = 5
    pool = multiprocessing.Pool(processes=pool_size, maxtasksperchild=10)

    try:
        jobs = {}
        for value in input_list:
            jobs[value] = pool.apply_async(input_function, [value])

        results = {}
        for value, result in jobs.items():
            try:
                results[value] = result.get()
            except KeyboardInterrupt:
                print "Interrupted by user"
                pool.terminate()
                break
            except Exception as e:
                results[value] = e
        return results
    except Exception:
        raise
    finally:
        pool.close()
        pool.join()


if __name__ == "__main__":
    iterations = range(100)
    t0 = datetime.now()
    results1 = apply_multiprocessing(iterations, test_func)
    t1 = datetime.now()
    print results1
    print "Multi: {}".format(t1 - t0)

    t2 = datetime.now()
    results2 = {i: test_func(i) for i in iterations}
    t3 = datetime.now()
    print results2
    print "Non-multi: {}".format(t3 - t2)

আউটপুট:

100
Multiprocessing run time: 0:00:41.131000
100
Non-multiprocessing run time: 0:03:20.688000

এই পদ্ধতির একটি সুবিধা হ'ল বাধা দেওয়ার আগে প্রক্রিয়া করা ফলাফলগুলি ফলাফলের অভিধানে ফিরে আসবে:

>>> apply_multiprocessing(range(100), test_func)
Interrupted by user
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

গৌরবময় এবং সম্পূর্ণ উদাহরণ
ইমটি

-5

আশ্চর্যজনকভাবে যথেষ্ট মনে হচ্ছে আপনাকে এটি পরিচালনা করতে হবে KeyboardInterrupt বাচ্চাদের মধ্যেও এটি । আমি এটি লিখিত হিসাবে কাজ করার আশা করতাম ... পরিবর্তনের চেষ্টা করুন slowly_square:

def slowly_square(i):
    try:
        sleep(1)
        return i * i
    except KeyboardInterrupt:
        print 'You EVIL bastard!'
        return 0

আপনার প্রত্যাশা অনুযায়ী এটি কাজ করা উচিত।


1
আমি এটি চেষ্টা করেছিলাম, এবং এটি আসলে কাজের পুরো সেটটি শেষ করে না। এটি বর্তমানে চলমান চাকরিগুলি সমাপ্ত করে, তবে স্ক্রিপ্টটি এখনও পুলগুলিতে অবশিষ্ট কাজগুলি বরাদ্দ করে ma ম্যাপ কলটি যেন সবকিছু স্বাভাবিক থাকে।
ফ্রেসওয়ার্থ

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