Python akışında join () kullanımı nedir?

Piton ipliklerini öğreniyordum ve join() üzerine tökezledi.

Yazar, iş parçacığı daemon modundaysa, ana iş parçacığı bitmeden iş parçacığının kendisini tamamlayabilmesi için join() kullanmam gerektiğini söyledi.

ama t.join() nasıl kullandığını da gördüm, ancak daemon t.join() çalışmamıştı.

örnek kod

 import threading import time import logging logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s', ) def daemon(): logging.debug('Starting') time.sleep(2) logging.debug('Exiting') d = threading.Thread(name='daemon', target=daemon) d.setDaemon(True) def non_daemon(): logging.debug('Starting') logging.debug('Exiting') t = threading.Thread(name='non-daemon', target=non_daemon) d.start() t.start() d.join() t.join() 

t.join() ne kullandığını bilmiyorum, çünkü bu bir arka plan programı değil ve t.join() bile herhangi bir değişiklik görmüyorum

127
26 февр. user192362127 tarafından 26 Şub tarihinde ayarlandı 2013-02-26 12:21 '13 12:21, 2013-02-26 12:21
@ 8 cevaplar

Mekanizmayı göstermek için birkaç beceriksiz sanat: join() bağlantısı, görünüşe göre ana iplik olarak adlandırılır. Aynı zamanda başka bir iplik tarafından da çağrılabilir, ancak gerek kalmadan diyagramı zorlaştırır.

join gelme-çağrı, ana akışın izine yerleştirilmelidir, ancak akışın ilişkisini ifade etmek ve mümkün olduğunca basitleştirmek için, onu çocuk akıntısına koymaya karar verdim.

 without join: +---+---+------------------ main-thread | | | +........... child-thread(short) +.................................. child-thread(long) with join +---+---+------------------***********+### main-thread | | | | +...........join() | child-thread(short) +......................join()...... child-thread(long) with join and daemon thread +-+--+---+------------------***********+### parent-thread | | | | | | +...........join() | child-thread(short) | +......................join()...... child-thread(long) +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, child-thread(long + daemonized) '-' main-thread/parent-thread/main-program execution '.' child-thread execution '#' optional parent-thread execution after join()-blocked parent-thread could continue '*' main-thread 'sleeping' in join-method, waiting for child-thread to finish ',' daemonized thread - 'ignores' lifetime of other threads; terminates when main-programs exits; is normally meant for join-independent tasks 

Bu nedenle, herhangi bir değişiklik görmemenizin nedeni, ana ipliğinizin üyeliğinizden sonra hiçbir şey yapmamasıdır. join (sadece) ana ipliğin yürütme ipliğiyle ilgili olduğunu söyleyebilirsiniz.

Örneğin, onları bir büyük sayfaya birleştirmek için aynı anda birkaç sayfa yüklemek isterseniz, akışları kullanarak paralel indirmeleri çalıştırabilirsiniz, ancak bir sayfa oluşturmaya başlamadan önce son sayfa / akışın tamamlanmasını beklemeniz gerekir. birçok. join() kullandığınız zaman budur.

201
26 февр. Cevap Don Soru 26 Şub verilir. 2013-02-26 13:00 '13 13:00 2013-02-26 13:00

Dokümanlardan düz

join ([Zaman aşımı]) Akışın tamamlanmasını bekleyin. Bu, çağıran iş parçacığını join () yöntemi sonlandırılana kadar - normal olarak veya işlenmeyen bir özel durum aracılığıyla - veya ek bir zaman aşımı oluşana kadar engeller.

Bu, t ve d oluşturan ana ipliğin, tamamlanıncaya kadar beklediği anlamına gelir.

Programınızın kullandığı mantığa bağlı olarak, ana iş parçacığınız devam etmeden önce iş parçacığının bitmesini bekleyebilirsiniz.

Ayrıca belgelerden:

Akış "daemon thread" olarak etiketlenebilir. Bu bayrağın anlamı, Python programının tamamının sadece daemon dişleri kaldığında sonlandırılmasıdır.

Basit bir örnek, şöyle diyoruz:

 def non_daemon(): time.sleep(5) print 'Test non-daemon' t = threading.Thread(name='non-daemon', target=non_daemon) t.start() 

Neyin sonu:

border=0
 print 'Test one' t.join() print 'Test two' 

Bu çıkacaktır:

 Test one Test non-daemon Test two 

Burada, ana iş parçacığı t iş parçasının sonuna kadar, ikinci kez print çağırıncaya kadar açıkça bekler.

Aksi takdirde, eğer bu olsaydı:

 print 'Test one' print 'Test two' t.join() 

Bu sonuca varıyoruz:

 Test one Test two Test non-daemon 

Burada işimizi ana iş parçacığında yapıyoruz ve daha sonra t iş parçacığının sonunu bekliyoruz. Bu durumda, açık t.join() bağlantısını bile kaldırabiliriz ve program tamamen t tamamlanmasını bekler.

49
26 февр. Cevap 26 Şubat dmg verilir. 2013-02-26 12:31 '13 12:31 2013-02-26 12:31

Bu konu için teşekkürler - bu da bana yardımcı oldu.

Bugün join () hakkında bir şeyler öğrendim.

Bu konular paralel olarak çalışır:

 d.start() t.start() d.join() t.join() 

ve sırayla yürütülürler (istediğimi değil):

 d.start() d.join() t.start() t.join() 

Özellikle, zekice ve dikkatlice denedim:

 class Kiki(threading.Thread): def __init__(self, time): super(Kiki, self).__init__() self.time = time self.start() self.join() 

İşe yarıyor! Ama sürekli çalışıyor. Ben self.start () 'ı __ init __' a koyabilirim, fakat self.join () 'e değil. Bu her iş parçacığı çalıştırdıktan sonra yapılmalıdır.

join (), ana iş parçacığının iş parçacığınızın tamamlanmasını beklemesini sağlayan şeydir. Aksi takdirde, iş parçacığınız kendi kendine çalışır.

Bu nedenle, ana iş parçacığı üzerinde join () işlevini "tutma" olarak düşünmenin yollarından biri, akışınızın akışını nasıl böldüğü ve ana akımın devam etmeden önce ana akışta sırayla yürütüldüğüdür. Ana iplik ileri hareket etmeden önce dişinizin tamamlanmasını sağlar. Bunun, join () çağrılmadan önce iş parçanızın zaten bitmiş olması normal olduğu anlamına gelir - ana iş parçacığı katılmak için çağrıdan hemen sonra serbest bırakılır ().

Aslında, ana iş parçacığı d.join () 'i bekliyor, ve d. iş parçacığı t.join ()' a girmeden önce tamamlanacak.

Aslında, çok açık olmak gerekirse, şu kodu göz önünde bulundurun:

 import threading import time class Kiki(threading.Thread): def __init__(self, time): super(Kiki, self).__init__() self.time = time self.start() def run(self): print self.time, " seconds start!" for i in range(0,self.time): time.sleep(1) print "1 sec of ", self.time print self.time, " seconds finished!" t1 = Kiki(3) t2 = Kiki(2) t3 = Kiki(1) t1.join() print "t1.join() finished" t2.join() print "t2.join() finished" t3.join() print "t3.join() finished" 

Bu çıktısını üretir (yazdırma talimatlarının birbirine nasıl eklendiğine dikkat edin.)

 $ python test_thread.py 32 seconds start! seconds start!1 seconds start! 1 sec of 1 1 sec of 1 seconds finished! 21 sec of 3 1 sec of 3 1 sec of 2 2 seconds finished! 1 sec of 3 3 seconds finished! t1.join() finished t2.join() finished t3.join() finished $ 

t1.join () ana iş parçacığını tutar. Her üç iş parçacığı t1.join () tamamlanmadan önce tamamlanır ve ana iş parçacığı yazdırmak için taşınır, ardından t2.join (), sonra yazdırır, sonra t3.join (), sonra yazdırır.

Düzeltmeler kabul edilir. Ayrıca akışta yeniyim.

(Not: İlgilendiğiniz takdirde, DrinkBot kodunu yazıyorum ve aynı anda malzemeleri pompalamaya başlamak için ipliği kesmem gerekiyor, sırayla değil - her içeceği beklemek için daha az zaman.)

26
20 мая '16 в 7:25 2016-05-20 07:25 Cevap Kiki Jewell tarafından 20 Mayıs '16 da, 07:25' de 2016-05-20 07:25

Join () yöntemi

join () yöntemi tamamlanmış bir iş parçacığı çağrılıncaya kadar çağıran iş parçacığını engeller.

Kaynak: http://docs.python.org/2/library/threading.html

13
26 февр. Cevap 26 Şubat tarihinde Ketouem tarafından verildi 2013-02-26 12:30 '13 12:30 2013-02-26 12:30

join(t) işlevi hem arka plan programı olmayan bir iş parçacığı için hem de arka plan iş parçacığı için işlevi yaparken, ana iş parçacığının (veya ana işlem) t saniye beklemesi ve ardından kendi işlemi üzerinde çalışmaya devam etmesi gerekir. t saniye bekletme süresi boyunca, her iki alt başlık da yapabileceklerini yapmalı, örneğin, bir metin basmalıdır. On saniye sonra, cennet dışı iş parçacığı hala işini tamamlamadıysa ve ana işlem işini tamamladıktan sonra da hala işini tamamlayabilirse, ama iş parçacığı iş parçacığı için olasılık penceresini kaçırdı. Ancak, sonunda Python programından çıktıktan sonra ölecek. Lütfen bir sorun varsa beni düzeltin.

1
09 сент. Tarafından cevap verilen kullanıcı1342336 Eyl 09 2013-09-09 17:39 '13, 17:39 2013-09-09 17:39

Basit bir deyişle, akış tamamlanana kadar bekleyin.

0
03 дек. Cevap Nehal Pawar 03 Aralık'ta verildi . 2018-12-03 10:37 '18, 10:37 2018-12-03 10:37

Bu örnek, .join() eylemini gösterir:

 import threading import time def threaded_worker(): for r in range(10): print('Other: ', r) time.sleep(2) thread_ = threading.Timer(1, threaded_worker) thread_.daemon = True # If the main thread kills, this thread will be killed too. thread_.start() flag = True for i in range(10): print('Main: ', i) time.sleep(2) if flag and i > 4: print( ''' Threaded_worker() joined to the main thread. Now we have a sequential behavior instead of concurrency. ''') thread_.join() flag = False 

dan:

 Main: 0 Other: 0 Main: 1 Other: 1 Main: 2 Other: 2 Main: 3 Other: 3 Main: 4 Other: 4 Main: 5 Other: 5 Threaded_worker() joined to the main thread. Now we have a sequential behavior instead of concurrency. Other: 6 Other: 7 Other: 8 Other: 9 Main: 6 Main: 7 Main: 8 Main: 9 
0
22 янв. Cevap 22 Ocak tarihinde Benyamin Jafari tarafından verildi. 2019-01-22 12:41 '19 , saat 12:41, 2019-01-22 12:41

"Join () kullanımı nedir?" sen söyle Gerçekten de, "Programları kapattığımda python ve OS benim için dosyamı kapattığından kapanış dosyalarının kullanılması?"

Bu sadece iyi bir programlama meselesidir. Akışınızın artık çalışmaması gereken koddaki bir noktadaki dizilerinize () katılmalısınız, çünkü akışın kendi kodunuza müdahale etmek için çalışmadığından veya daha büyük bir sisteme doğru davranmak istediğinizden emin olmanız gerekir. .

Söyleyebilirsiniz: “Kodumun yanıtı vermeyi geciktirmesini istemiyorum”, ancak bağlantı kurması için harcayabileceği fazladan zaman () olabilir. Bu, bazı senaryolarda oldukça doğru olabilir, ancak şimdi kodunuzun "temizlik için piton ve işletim sistemi etrafında serin kaldığını" dikkate almanız gerekir. Bunu performans nedenleriyle yapıyorsanız, bu davranışı belgelemenizi şiddetle tavsiye ederim. Bu, özellikle başkalarının kullanması gereken bir kütüphane / paket oluşturuyorsanız geçerlidir.

Performansın nedenleri dışında () 'a katılmamak için hiçbir sebep yok ve kodunuzun buna gerek duymadığını söyleyebilirim.

-3
20 дек. Tarafından cevap Chris Cogdon Aralık 20 2013-12-20 02:05 '13, 02:05 2013-12-20 02:05