Ana program bittiğinde iş parçacığı nasıl sonlandırılır?


86

Sonsuz döngüde bir iş parçacığım varsa, ana program sona erdiğinde onu sonlandırmanın bir yolu var mı (örneğin, Ctrl+ düğmesine bastığımda C)?

Yanıtlar:


46

Bu soruyu kontrol edin. Doğru cevap, iş parçacıklarının doğru şekilde nasıl sonlandırılacağına dair harika bir açıklamaya sahiptir: Python'da bir İş Parçacığını öldürmenin herhangi bir yolu var mı?

İş parçacığını Keyboard Interrupt sinyalinde (ctrl + c) durdurmak için "KeyboardInterrupt" istisnasını yakalayabilir ve çıkmadan önce temizleyebilirsiniz. Bunun gibi:

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

Bu şekilde, program aniden sonlandırıldığında ne yapacağınızı kontrol edebilirsiniz.

Ayrıca, sinyal işleyicileri (sizin özel durumunuzda SIGINT sinyali) kurmanıza izin veren yerleşik sinyal modülünü de kullanabilirsiniz: http://docs.python.org/library/signal.html


Cevabınız için çok teşekkürler. Soruyu doğru söylememiş olabilirim. Bu soruda verilen örnekte, iş parçacığının stop () işlevini yürütmek hala gerekliydi. Bir programı ctrl + C ile anormal şekilde sonlandırdığımda, bu olamaz. Öyleyse, sorum biraz "Ana iş parçacığı akışı kesilirse, mitread.stop () işlevini nasıl çağırırım" gibi
facha

1
cleanup_stop_thread()ı kullanabileceği bir küresel işlev? yoksa uygulamam mı gerekiyor?
alper

@alper, sanırım bu sadece bir şeyi uygulamak mümkün olan bir örnekti. Bunu uygulamalısın
Leonardo Rick

100

Çalışan iş parçacıklarınızı daemon evreleri oluşturursanız, tüm arka plan programı olmayan evreleriniz (örneğin ana iş parçacığı) çıkıldığında ölürler.

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


4
Basit ve kesin cevap için teşekkürler, varsayılan iş parçacığı. İş parçacığı durumu isDaemon()False, tarafından True olarak ayarlayın setDaemon(True).
Tong

3
Bu soruyu cevaplar ve sadece işe yarar. Operasyon genel olarak iplerden nasıl temiz bir şekilde çıkılacağını sormadı.
Johannes Overmann

1
isDaemon()ve setDaemon()(bağlı doküman yukarıdaki gibi), kullanımdan hemen eski alıcılar / ayarlayıcıları olarak daemon=Trueiçindethreading.Thread()
fabio.sang

1
Arka

Artalan süreci iş parçacıklarını kullanmaktan kaçınmak ve iş parçacıklarını temiz bir şekilde sonlandırmak için, bkz. Stackoverflow.com/questions/58910372/…
kullanıcı

15

Alt iş parçacığını daemon iş parçacığı olarak etkinleştirmeyi deneyin.

Örneğin:

Önerilen:

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()

Çizgide:

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

Eski API:

t.setDaemon(True)
t.start()

Ana iş parçacığınız sona erdiğinde ("yani Ctrl+ düğmesine bastığımda C"), diğer iş parçacıkları da yukarıdaki talimatlar tarafından öldürülür.


1
Arka

12

Kullanım atexit gibi yakalanmamış istisna olmak üzere ana iş parçacığı herhangi makul "temiz" feshi hakkında (ana iş parçacığı üzerinde) denilen olsun "sonlandırma" fonksiyonlarını kaydetmek için Python'ın standart kütüphanenin modülü KeyboardInterrupt. Bu tür sonlandırma işlevleri (kaçınılmaz olarak ana iş parçacığında!) İstediğiniz herhangi bir stopişlevi çağırabilir ; daemonihtiyaç duyduğunuz sistem işlevselliğini doğru bir şekilde tasarlamanız için gerekli araçları sağlayan bir iş parçacığı ayarlama olasılığı ile birlikte .


Bu yaklaşımın 2.6.5'ten önceki Python sürümlerinde daemonize edilmiş iş parçacıkları gerektirmeden çalıştığını unutmayın, stackoverflow.com/questions/3713360/… . Bu talihsiz bir IMHO'dur, çünkü kapatma sırasında artalan süreçleri python 3.4'ten önce biraz karışıktır ( bugs.python.org/issue19466 ). Durdurursanız ve sizin atexit işleyicileri içinde cini konuları katılmak, tüm iplik söküm seri hale (muhtemelen önemsiz) maliyetle, ince olmalıdır.
NeilenMarais

atexit.register()Python modüllerindeki post-poned çağrılar nedeniyle tuhaf şeyler olabileceğinin farkında olun , bu da sonlandırma prosedürünüzün prosedüründen sonra yürütülmesine neden olur multiprocessing. Bu sorunla Queueve daemoniş parçacıklarıyla uğraşıyorum : Çoklu işlem Kuyruğu ve İş Parçacığı kullanılarak program çıkışında "EOF hatası" .
Delgan

Görünüşe göre 3.7.4+ gibi Python'un modern sürümlerinde, atexitişleyiciler, arka plan programı olmayan iş parçacıkları canlı olduğunda ve ana iş parçacığı çıktığında çağrılmaz. Konuları sonlandırmak için atexit kullanılırken çıkışta komut dosyası takılı kaldı bölümüne bakın .
martineau

9

Böyle bir İplik üretirseniz - myThread = Thread(target = function)- ve sonra yapın myThread.start(); myThread.join(). CTRL-C başlatıldığında, ana iş parçacığı bu engelleme myThread.join()çağrısını beklediği için çıkmaz . Bunu düzeltmek için, .join () çağrısına bir zaman aşımı koyun. Zaman aşımı istediğiniz kadar uzun olabilir. Süresiz olarak beklemesini istiyorsanız, 99999 gibi gerçekten uzun bir zaman aşımı süresi koyun. myThread.daemon = TrueAna iş parçacığı (arka plan programı olmayan) çıktığında tüm iş parçacıklarının çıkması da iyi bir uygulamadır .


myThread.daemon = Truebu soruna harika bir çözüm.
Brannon

5
@Brannon .daemon=Truesağlam bir çözümde değil. Açıklama için bu konuyu kontrol edin: stackoverflow.com/a/20598791/5562492
Odyssee

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.