Saya sedang mempelajari threading python dan menemukan join()
.
Penulis mengatakan bahwa jika utas berada dalam mode daemon maka saya perlu menggunakan join()
agar utas dapat menyelesaikan sendiri sebelum utas utama berakhir.
tapi saya juga pernah melihatnya menggunakan t.join()
meskipun t
tidakdaemon
contoh kode adalah ini
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()
saya tidak tahu apa yang digunakan t.join()
karena ini bukan daemon dan saya tidak dapat melihat perubahan meskipun saya menghapusnya
python
multithreading
python-multithreading
pengguna192362127
sumber
sumber
Jawaban:
Sebuah seni yang agak kikuk untuk mendemonstrasikan mekanismenya:
join()
Agaknya disebut oleh utas-utas. Itu bisa juga dipanggil oleh utas lain, tetapi tidak perlu menyulitkan diagram.join
-calling harus ditempatkan di jalur main-thread, tetapi untuk mengekspresikan hubungan-thread dan menjaganya sesederhana mungkin, saya memilih untuk menempatkannya di child-thread sebagai gantinya.Jadi alasan Anda tidak melihat perubahan adalah karena utas utama Anda tidak melakukan apa pun setelah Anda
join
. Bisa dibilangjoin
relevan (hanya) untuk alur eksekusi dari utas utama.Jika, misalnya, Anda ingin secara bersamaan mengunduh banyak halaman untuk menggabungkannya menjadi satu halaman besar, Anda dapat mulai mengunduh secara bersamaan menggunakan utas, tetapi perlu menunggu sampai halaman / utas terakhir selesai sebelum Anda mulai menyusun satu halaman dari banyak. Saat itulah Anda menggunakan
join()
.sumber
demon_thread.join(0.0)
,join()
secara default memblokir tanpa memperhatikan atribut daemonized. Tetapi bergabung dengan utas setan membuka kemungkinan besar keseluruhan masalah! Saya sekarang sedang mempertimbangkan untuk menghapusjoin()
panggilan dalam diagram kecil saya untuk daemon-thread ...daemon=True
tidak kita perlu kejoin()
jika kita perlujoin()
di akhir kode?main thread
selesai, akankah program selesai tanpa membiarkanchild-thread(long)
selesai berjalan sendiri (yaituchild-thread(long)
tidak sepenuhnya dilakukan)?Langsung dari dokumen
Ini berarti bahwa utas utama yang memunculkan
t
dand
, menunggu untukt
selesai sampai selesai.Bergantung pada logika yang digunakan program Anda, Anda mungkin ingin menunggu sampai utas selesai sebelum utas utama berlanjut.
Juga dari dokumen:
Contoh sederhana, katakan kita memiliki ini:
Yang diakhiri dengan:
Ini akan menampilkan:
Di sini master thread secara eksplisit menunggu sampai
t
thread selesai sampai ia memanggilprint
yang kedua kalinya.Atau kalau kita punya ini:
Kami akan mendapatkan hasil ini:
Di sini kita melakukan pekerjaan kita di utas utama dan kemudian kita menunggu
t
utas selesai. Dalam hal ini kita bahkan mungkin menghapus bergabung secara eksplisitt.join()
dan program secara implisit akan menunggu untukt
selesai.sumber
t.join()
? dengan menambahkan tidur malam atau sesuatu yang lain. saat ini saya dapat melihat chnage dalam program bahkan jika saya menggunakannya atau tidak. tetapi untuk damemon saya dapat melihat keluarnya jika saya menggunakand.join()
yang saya tidak lihat ketika saya tidak menggunakan d.join ()Terima kasih atas utas ini - ini banyak membantu saya.
Saya belajar sesuatu tentang .join () hari ini.
Utas ini berjalan secara paralel:
dan ini berjalan secara berurutan (bukan yang saya inginkan):
Secara khusus, saya mencoba untuk pintar dan rapi:
Ini bekerja! Tapi itu berjalan berurutan. Saya bisa meletakkan self.start () di __ init __, tetapi bukan self.join (). Itu harus dilakukan setelah setiap utas dimulai.
join () adalah apa yang menyebabkan utas utama menunggu utas Anda selesai. Jika tidak, utas Anda berjalan dengan sendirinya.
Jadi salah satu cara untuk menganggap join () sebagai "tahan" pada utas utama - itu semacam mencabut utas dan menjalankan secara berurutan pada utas utama, sebelum utas utama dapat dilanjutkan. Ini memastikan bahwa utas Anda selesai sebelum utas utama bergerak maju. Perhatikan bahwa ini berarti tidak apa-apa jika utas Anda sudah selesai sebelum Anda memanggil join () - utas utama dilepaskan segera saat join () dipanggil.
Sebenarnya, barusan saya sadar bahwa utas utama menunggu di d.join () hingga utas d selesai sebelum beralih ke t.join ().
Bahkan, agar sangat jelas, pertimbangkan kode ini:
Ini menghasilkan output ini (perhatikan bagaimana pernyataan cetak saling berulir.)
T1.join () sedang memegang utas utama. Ketiga utas selesai sebelum t1.join () selesai dan utas utama melanjutkan untuk menjalankan cetak kemudian t2.join () kemudian cetak lalu t3.join () lalu cetak.
Selamat datang koreksi. Saya juga baru mengenal threading.
(Catatan: jika Anda tertarik, saya menulis kode untuk DrinkBot, dan saya perlu threading untuk menjalankan pompa bahan secara bersamaan daripada berurutan - lebih sedikit waktu untuk menunggu setiap minuman.)
sumber
Metode bergabung ()
Sumber: http://docs.python.org/2/library/threading.html
sumber
t.join()
dan program masih menunggu sebelum penghentian. saya tidak melihat ada gunanyat.join()
di sini dalam kode sayaMemahami sederhana,
dengan join - interpreter akan menunggu sampai proses Anda selesai atau dihentikan
tanpa bergabung - penerjemah tidak akan menunggu sampai proses dihentikan ,
sumber
Saat membuat
join(t)
fungsi untuk utas non-daemon dan utas daemon, utas utama (atau proses utama) harus menunggu beberapat
detik, kemudian dapat melangkah lebih jauh untuk mengerjakan prosesnya sendiri. Selamat
waktu tunggu detik, kedua utas anak-anak harus melakukan apa yang dapat mereka lakukan, seperti mencetak beberapa teks. Setelah beberapat
detik, jika utas non-daemon masih belum menyelesaikan tugasnya, dan masih bisa menyelesaikannya setelah proses utama menyelesaikan tugasnya, tetapi untuk utas daemon, ia hanya melewatkan jendela peluangnya. Namun, akhirnya akan mati setelah program python keluar. Harap perbaiki saya jika ada sesuatu yang salah.sumber
Dalam python 3.x join () digunakan untuk bergabung dengan utas dengan utas utama yaitu ketika join () digunakan untuk utas tertentu, utas utama akan berhenti dieksekusi sampai eksekusi utas gabungan selesai.
sumber
Contoh ini menunjukkan
.join()
tindakan:Di luar:
sumber
Ada beberapa alasan mengapa utas utama (atau utas lainnya) bergabung dengan utas lainnya
Utas mungkin telah membuat atau menahan (mengunci) beberapa sumber. Utas panggilan gabungan mungkin dapat menghapus sumber daya atas namanya
join () adalah panggilan pemblokiran alami untuk utas panggilan penggabungan untuk melanjutkan setelah utas yang dipanggil dihentikan.
Jika program python tidak bergabung dengan utas lain, juru bahasa python masih akan bergabung dengan utas non-daemon atas namanya.
sumber
"Apa gunanya menggunakan join ()?" kamu bilang. Sungguh, itu jawaban yang sama dengan "apa gunanya menutup file, karena python dan OS akan menutup file saya ketika program saya keluar?".
Ini hanya masalah pemrograman yang bagus. Anda harus bergabung () utas pada titik di kode bahwa utas tidak boleh berjalan lagi, baik karena Anda harus memastikan utas tidak berjalan untuk mengganggu kode Anda sendiri, atau bahwa Anda ingin berperilaku dengan benar dalam sistem yang lebih besar.
Anda mungkin berkata "Saya tidak ingin kode saya menunda memberikan jawaban" hanya karena waktu tambahan yang diperlukan untuk bergabung (). Ini mungkin benar-benar valid dalam beberapa skenario, tetapi Anda sekarang harus mempertimbangkan bahwa kode Anda "meninggalkan penggerusan untuk python dan OS untuk dibersihkan". Jika Anda melakukan ini karena alasan kinerja, saya sangat menyarankan Anda untuk mendokumentasikan perilaku itu. Ini terutama benar jika Anda sedang membangun perpustakaan / paket yang diharapkan orang lain manfaatkan.
Tidak ada alasan untuk tidak bergabung (), selain alasan kinerja, dan saya berpendapat bahwa kode Anda tidak perlu melakukan itu dengan baik.
sumber
join()
.