Apa yang terjadi pada sebuah thread terpisah ketika main() keluar?
Asumsikan I'm mulai std::benang
dan kemudian detach()
itu, sehingga benang terus mengeksekusi meskipun std::benang
yang pernah mewakili itu, berjalan keluar dari ruang lingkup.
Asumsikan lebih lanjut bahwa program ini tidak memiliki protokol yang reliable untuk bergabung dengan terpisah benang1, sehingga terpisah benang masih berjalan saat main()
keluar.
Saya tidak dapat menemukan apa-apa dalam standar (lebih tepatnya, di N3797 C++14 raperda), yang menjelaskan apa yang harus terjadi, baik 1.10 atau 30.3 mengandung kata-kata yang bersangkutan.
1 yang Lain, mungkin setara, pertanyaannya adalah: "dapat terpisah thread yang pernah bergabung lagi", karena apapun protokol anda're inventing untuk bergabung, yang menandakan bagian yang harus dilakukan ketika benang itu masih berjalan, dan OS scheduler mungkin memutuskan untuk menempatkan benang untuk tidur selama satu jam setelah sinyal dilakukan dengan tidak ada cara untuk menerima akhir untuk andal mendeteksi bahwa benang benar-benar selesai.
Jika kehabisan main()
terpisah dengan benang berjalan adalah perilaku tidak terdefinisi, maka any penggunaan std::benang::detach()
adalah perilaku tidak terdefinisi kecuali thread utama tidak pernah keluar2.
Dengan demikian, berjalan keluar dari main()
dengan terpisah thread yang berjalan harus memiliki defined efek. Pertanyaannya adalah: where (di C++ standard, tidak POSIX, bukan OS dokumen, ...) adalah efek-efek ditetapkan.
2 terpisah thread tidak dapat bergabung (dalam arti std::benang::join()
). Anda can menunggu hasil dari terpisah benang (misalnya melalui masa depan dari std::packaged_task
, atau dengan counting semaphore atau bendera dan kondisi variabel), tapi itu doesn't menjamin bahwa topik pesan telah selesai executing. Memang, kecuali anda menempatkan sinyal ke bagian destructor pertama otomatis objek dari benang, ada will, secara umum, sama kode (destruktor) yang menjalankan after signaling kode. Jika OS jadwal thread utama untuk mengkonsumsi hasil dan keluar sebelum melepaskan benang selesai menjalankan berkata destructors, apa yang akan^Wis didefinisikan terjadi?
Jawaban untuk pertanyaan asli "apa yang terjadi pada sebuah thread terpisah saat
main()
keluar" adalah:Hal ini terus berjalan (karena standar doesn't mengatakan itu dihentikan), dan yang's didefinisikan dengan baik, selama itu tidak menyentuh (otomatis|thread_local) variabel-variabel lain benang atau benda statis.
Hal ini tampaknya akan diizinkan untuk memungkinkan benang manajer sebagai objek statis (catatan di [dasar.mulai.istilah]/4 kata lebih banyak, terima kasih untuk @dyp untuk pointer).
Masalah timbul ketika penghancuran objek statis telah selesai, karena kemudian eksekusi memasuki rezim di mana hanya kode diperbolehkan dalam penanganan sinyal dapat mengeksekusi ([dasar.mulai.istilah]/1, 1 kalimat). C++ standar library, yang hanya
<atom>
library ([dukungan.runtime]/9, 2 kalimat). Khususnya, yang—secara umum—tidak termasukcondition_variable
(it's pelaksanaannya ditetapkan apakah yang menyimpan untuk digunakan dalam sinyal handler, karena itu's bukan bagian dari<atom>
).Kecuali anda've dibatalkan stack pada titik ini, itu's sulit untuk melihat bagaimana untuk menghindari perilaku tidak terdefinisi.
Jawaban untuk kedua pertanyaan "dapat terlepas benang pernah bergabung lagi" adalah:
Ya, dengan
*_at_thread_exit
keluarga fungsi (notify_all_at_thread_exit()
,std::janji::set_value_at_thread_exit()
, ...).Seperti yang tercantum dalam catatan kaki [2] dari pertanyaan, menandakan kondisi variabel atau semaphore atau atom counter tidak cukup untuk bergabung terpisah thread (dalam arti memastikan bahwa akhir eksekusi telah-terjadi-sebelum menerima kata signalling dengan menunggu thread), karena, pada umumnya, akan ada lebih banyak kode dieksekusi setelah misalnya
notify_all()
dari kondisi variabel, khususnya destruktor otomatis dan benang-objek lokal.Menjalankan sinyal sebagai hal terakhir benang tidak (setelah destruktor otomatis dan benang-objek lokal telah-terjadi) adalah apa yang
_at_thread_exit
keluarga fungsi dirancang untuk.Jadi, dalam rangka untuk menghindari perilaku tidak terdefinisi dalam tidak adanya pelaksanaan jaminan atas apa yang standar membutuhkan, anda perlu (manual) bergabung terpisah benang dengan
_at_thread_exit
fungsi melakukan signaling atau membuat thread terpisah mengeksekusi hanya kode yang akan aman untuk sinyal handler juga.Memisahkan Benang
Menurut
std::benang::melepaskan
:Dari
pthread_detach
:Memisahkan benang ini terutama untuk menghemat sumber daya, dalam kasus aplikasi tidak perlu menunggu benang untuk menyelesaikan (misalnya daemon, yang harus dijalankan sampai proses terminasi):
std::benang
objek keluar dari ruang lingkup tanpa bergabung, apa yang biasanya mengarah ke panggilan untukstd::menghentikan()
pada kehancuran.Membunuh Benang
Perilaku penghentian proses adalah sama sebagai salah satu thread utama, yang setidaknya bisa menangkap sinyal. Apakah atau tidak benang lain dapat menangani sinyal tidak begitu penting, sebagai salah satu bisa bergabung atau menghentikan thread lainnya di dalam thread utama's sinyal handler doa. (Terkait pertanyaan)
Seperti yang sudah disebutkan, thread apapun, baik terpisah atau tidak, akan mati dengan proses pada kebanyakan Os. Proses itu sendiri dapat dihentikan dengan menaikkan sinyal, dengan memanggil
exit()
atau kembali dari fungsi utama. Namun, C++11 tidak dapat dan tidak mencoba untuk menentukan secara tepat perilaku yang mendasari OS, sedangkan para pengembang Java VM pasti bisa abstrak perbedaan tersebut sampai batas tertentu. AFAIK, eksotis proses dan model threading yang biasanya ditemukan pada platform kuno (yang C++11 mungkin tidak't porting) dan berbagai sistem embedded, yang bisa memiliki khusus dan/atau terbatas bahasa implementasi perpustakaan dan juga terbatas dukungan bahasa.Benang Dukungan
Jika benang tidak't didukung
std::benang::get_id()
harus mengembalikan invalid id (default dibangunstd::benang::id
) seperti yang ada's polos proses, yang tidak membutuhkan benang objek untuk menjalankan dan konstruktorstd::benang
harus membuangstd::system_error
. Ini adalah bagaimana saya memahami C++11 dalam hubungannya dengan hari ini's Os. Jika ada's OS dengan threading dukungan, yang doesn't menelurkan sebuah thread utama dalam proses, biarkan aku tahu.Mengendalikan Benang
Jika salah satu kebutuhan untuk menjaga kontrol atas benang untuk shutdown yang tepat, seseorang dapat melakukannya dengan menggunakan sync primitif dan/atau semacam bendera. Namun, Dalam kasus ini, pengaturan shutdown bendera diikuti dengan bergabung adalah cara saya sukai, karena ada's tidak ada titik dalam meningkatkan kompleksitas dengan memisahkan benang, sebagai sumber daya yang akan dibebaskan pada waktu yang sama pula, di mana beberapa byte dari
std::benang
obyek vs kompleksitas yang lebih tinggi dan mungkin lebih sync primitif harus diterima.Nasib benang setelah keluar program yang tidak terdefinisi perilaku. Tapi sistem operasi modern akan membersihkan semua thread yang dibuat oleh proses penutupan itu.
Ketika memisahkan sebuah
std::benang
, tiga kondisi ini akan terus mengadakan:*ini
tidak lagi memiliki benang punjoinable()
akan selalu sama denganpalsu
get_id()
samastd::benang::id()
Perhatikan kode berikut:
Ketika thread utama (yaitu, benang yang menjalankan fungsi main ()) berakhir, maka proses dihentikan dan semua thread lain berhenti.
Referensi: https://stackoverflow.com/a/4667273/2194843
Untuk memungkinkan thread lain untuk melanjutkan eksekusi, thread utama harus mengakhiri dengan memanggil pthread_exit() daripada keluar(3). It's baik-baik saja untuk menggunakan pthread_exit di utama. Ketika pthread_exit digunakan, thread utama akan berhenti mengeksekusi dan akan tetap di zombie(mati) status sampai semua benang lain yang keluar. Jika anda menggunakan pthread_exit di thread utama, tidak bisa mendapatkan kembali status dari benang lain dan tidak bisa melakukan clean-up untuk thread lain (bisa dilakukan dengan menggunakan pthread_join(3)). Juga, it's baik untuk melepaskan benang(pthread_detach(3)) sehingga benang daya secara otomatis dirilis pada thread penghentian. Sumber daya yang dibagi tidak akan dibebaskan sampai semua benang yang keluar.