মূল প্রোগ্রামটি শেষ হয়ে গেলে কীভাবে কোনও থ্রেড শেষ করবেন?


86

যদি আমার কাছে অসীম লুপটিতে একটি থ্রেড থাকে, মূল প্রোগ্রামটি শেষ হয়ে গেলে এটি বন্ধ করার কোনও উপায় আছে (উদাহরণস্বরূপ, যখন আমি Ctrl+ টিপবো C)?

উত্তর:


46

এই প্রশ্নটি পরীক্ষা করুন। সঠিক উত্তরটি কীভাবে থ্রেডগুলি সঠিকভাবে শেষ করতে হয় তার দুর্দান্ত ব্যাখ্যা রয়েছে: পাইথনে কোনও থ্রেডকে মেরে ফেলার কোনও উপায় আছে কি?

কীবোর্ড ইন্টারপ্রেট সিগন্যালে থ্রেডটি থামাতে (সিটিআরএল + সি) আপনি প্রস্থান করার আগে ব্যতিক্রম "কীবোর্ড ইন্টারটার্ট" এবং ক্লিনআপটি ধরতে পারেন। এটার মত:

try:
    start_thread()  
except (KeyboardInterrupt, SystemExit):
    cleanup_stop_thread()
    sys.exit()

প্রোগ্রামটি হঠাৎ করে বন্ধ হয়ে গেলে আপনি কী করবেন তা আপনি নিয়ন্ত্রণ করতে পারেন control

আপনি অন্তর্নির্মিত সিগন্যাল মডিউলটিও ব্যবহার করতে পারেন যা আপনাকে সিগন্যাল হ্যান্ডেলারগুলি সেটআপ করতে দেয় (আপনার নির্দিষ্ট ক্ষেত্রে সাইন ইন সিগন্যাল): http://docs.python.org/library/signal.html


আপনার প্রতিউত্তরের জন্য ধন্যবাদ. আমি প্রশ্নটি সঠিকভাবে না বলে থাকতে পারি। এই প্রশ্নে দেওয়া উদাহরণে থ্রেডের স্টপ () ফাংশনটি কার্যকর করা এখনও প্রয়োজনীয় ছিল। আমি যখন সিটিটিএল + সি দ্বারা অস্বাভাবিকভাবে কোনও প্রোগ্রামটি শেষ করি, তখন এটি হতে পারে না। সুতরাং, আমার প্রশ্নটি কিছুটা এইরকম, "মূল থ্রেড প্রবাহ বাধাগ্রস্ত হলে আমি কীভাবে পৌরাণিক কাহিনীকে স্টপ ()
ফানসিওন বলব

4
কি cleanup_stop_thread()একটি বিশ্বব্যাপী ফাংশন যে আমি ব্যবহার করতে পারি? বা আমার এটি প্রয়োগ করা উচিত?
আল্পার

@ লম্পার, আমি মনে করি এটি সম্ভবত একটি উদাহরণ যা কিছু বাস্তবায়ন সম্ভব। আপনার এটি প্রয়োগ করা উচিত
লিওনার্দো রিক

100

আপনি যদি আপনার কর্মী থ্রেডকে ডেমন থ্রেড তৈরি করেন তবে আপনার সমস্ত ডিমন-থ্রেড (যেমন মূল থ্রেড) বেরিয়ে আসার পরে তারা মারা যাবে।

http://docs.python.org/library/threading.html#threading.Thread.daemon


4
সাধারণ এবং সুনির্দিষ্ট উত্তরের জন্য ধন্যবাদ, ডিফল্ট থ্রেডিং h থ্রেড ডিমন স্ট্যাটাসটি isDaemon()মিথ্যা, এটিকে সত্য দ্বারা সেট করুন setDaemon(True)
টং

4
এটি প্রশ্নের উত্তর দেয় এবং ঠিক কাজ করে। সাধারণভাবে থ্রেডগুলি কীভাবে পরিষ্কারভাবে প্রস্থান করবেন তা অপ্টটি জিজ্ঞাসা করেনি।
জোহানেস ওভারম্যান

4
isDaemon()এবং setDaemon()পুরাতন getters / setters হয় (উপরে লিঙ্ক ডক অনুযায়ী), শুধু ব্যবহার daemon=Trueমধ্যেthreading.Thread()
fabio.sang

4
লক্ষ্য করুন ডেমন থ্রেড ব্যবহার করে অন্যান্য সমস্যা সৃষ্ঠি পারে এবং সম্ভবত না কি তুমি এখানে চাই: stackoverflow.com/questions/20596918/...
Doopy

ডেমন থ্রেডগুলি ব্যবহার করা এবং পরিষ্কারভাবে থ্রেডগুলিকে হত্যা করতে এড়াতে দেখুন stackoverflow.com/questions/58910372/…
ব্যবহারকারী

15

সাব-থ্রেডটি ডেমন-থ্রেড হিসাবে সক্ষম করার চেষ্টা করুন।

এই ক্ষেত্রে:

প্রস্তাবিত:

from threading import Thread

t = Thread(target=<your-method>)
t.daemon = True  # This thread dies when main thread (only non-daemon thread) exits.
t.start()

সারিতে:

t = Thread(target=<your-method>, daemon=True).start()

পুরানো এপিআই:

t.setDaemon(True)
t.start()

যখন আপনার মূল থ্রেডটি সমাপ্ত হবে ("যখন আমি Ctrl+ টিপব C" তখন) অন্য থ্রেডগুলিও উপরের নির্দেশাবলীর দ্বারা মারা যাবে।


4
লক্ষ্য করুন ডেমন থ্রেড ব্যবহার করে অন্যান্য সমস্যা সৃষ্ঠি এবং সম্ভবত হয় না তুমি এখানে কি আপনি চান করতে পারেন: stackoverflow.com/questions/20596918/...
Doopy

12

ব্যবহার করুন atexit প্রধান থ্রেডের কোনো যুক্তিসঙ্গতভাবে "পরিষ্কার" পরিসমাপ্তি, যেমন একটি uncaught ব্যতিক্রম সহ "পরিসমাপ্তি" ফাংশন (প্রধান থ্রেডে) যে বলা পেতে নিবন্ধন করতে পাইথন এর স্ট্যান্ডার্ড লাইব্রেরির মডিউল KeyboardInterrupt। এই ধরনের সমাপ্তি ফাংশনগুলি (যদিও অবশ্যম্ভাবী মূল থ্রেডে থাকে!) stopআপনার প্রয়োজনীয় কোনও ফাংশন কল করতে পারে; একসাথে একটি থ্রেড সেট করার সম্ভাবনার সাথে daemon, এটি আপনাকে আপনার প্রয়োজনীয় সিস্টেমের কার্যকারিতাটি সঠিকভাবে ডিজাইনের সরঞ্জাম সরবরাহ করে।


লক্ষ্য করুন এই পদ্ধতির 2.6.5 পূর্বে পাইথন সংস্করণে daemonized থ্রেড প্রয়োজন ছাড়া কাজ করেন, উত্তর দেখুন stackoverflow.com/questions/3713360/... । এটি দুর্ভাগ্যজনক আইএমএইচও, যেহেতু শাটডাউন চলাকালীন ডেমন থ্রেডগুলি অজগর ৩.৪ এর আগে কিছুটা গোলমাল করে ( বাগস.পাইথন.আর । / বিসুক ১৯৪66 )। যদি আপনি আটকে থাকেন এবং আপনার অ্যাক্সিট হ্যান্ডলারগুলিতে আপনার ডেমন থ্রেডগুলিতে যোগদান করেন তবে আপনার থ্রেড টিয়ারডাউন সিরিয়ালাইজ করার জন্য (সম্ভবত তুচ্ছ) ব্যয়বহুল সমস্ত কিছু ঠিক আছে।
নিলেনমারায়েস

অজানা থাকুন যে atexit.register()পাইথন মডিউলগুলিতে পোস্ট-পোনড কলগুলির কারণে অদ্ভুত জিনিসগুলি ঘটতে পারে , যার ফলে আপনার সমাপ্তির প্রক্রিয়াটি এর পরে কার্যকর করা হবে multiprocessing। আমি এই সমস্যাটির সাথে ড্রেডিংQueue এবং daemonথ্রেডগুলিতে চালাচ্ছি : মাল্টিপ্রসেসিং ক্যু এবং থ্রেড ব্যবহার করে প্রোগ্রাম প্রস্থান করার সময় "EOF ত্রুটি"
দেলগান

স্পষ্টতই পাইথনের আধুনিক সংস্করণগুলিতে, যেমন 7. non.৪++ atexitনন-ডেমন থ্রেডগুলি বেঁচে থাকে এবং মূল থ্রেডটি প্রস্থান হয় তখন হ্যান্ডলারগুলি বলা হয় না। থ্রেড সমাপ্ত করতে অক্ষর ব্যবহার করার সময় স্ক্রিপ্টটি প্রস্থান করতে গিয়ে আটকে দেখুন ।
মার্টিনো

9

যদি আপনি এমন একটি থ্রেড স্প্যান করেন - myThread = Thread(target = function)- এবং তারপর করুন myThread.start(); myThread.join()। যখন সিটিআরএল-সি শুরু করা হয়, মূল থ্রেডটি প্রস্থান করে না কারণ এটি সেই ব্লকিং myThread.join()কলটির জন্য অপেক্ষা করছে । এটি ঠিক করতে, কেবলমাত্র .join () কলটিতে একটি সময়সীমা রেখে। সময়সীমা আপনার ইচ্ছামতো দীর্ঘ হতে পারে। আপনি যদি এটি অনির্দিষ্টকালের জন্য অপেক্ষা করতে চান তবে 99999 এর মতো একটি দীর্ঘ দীর্ঘ সময়সীমা রেখে দিন myThread.daemon = Truethe মূল থ্রেড (নন-ডিমন) প্রস্থান করলে সমস্ত থ্রেডগুলি প্রস্থান করার জন্য এটি করাও ভাল অনুশীলন ।


myThread.daemon = Trueএই সমস্যার একটি দুর্দান্ত সমাধান।
ব্রানন

4
@ ব্রানন .daemon=Trueএকটি শক্ত সমাধান নয়। ব্যাখ্যার জন্য এই থ্রেডটি দেখুন: stackoverflow.com/a/20598791/5562492
ওডিসি

2

ডেমন থ্রেডগুলি অনগ্রসরভাবে হত্যা করা হয় যাতে কোনও চূড়ান্ত নির্দেশিকা কার্যকর করা হয় না। একটি সম্ভাব্য সমাধান চেক করা হয় মূল থ্রেডটি অসীম লুপের পরিবর্তে জীবিত।

পাইথন 3 এর উদাহরণস্বরূপ:

while threading.main_thread().isAlive():
    do.you.subthread.thing()
gracefully.close.the.thread()

অন্য থ্রেড থেকে মূল থ্রেডটি এখনও বেঁচে আছে কিনা তা দেখুন ।

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