Bagaimana cara tidur thread?

14

Ketika Anda tidur utas, apa yang sebenarnya terjadi?

Saya melihat bahwa menidurkan utas "menjeda utas saat ini untuk jangka waktu tertentu" . Tapi bagaimana cara kerjanya?

Menurut How Thread.sleep () bekerja secara internal dan Bagaimana Thread.sleep benar-benar berfungsi? :

  • durasi tidur akan dikenakan granularity khusus sistem
  • tidur menghalangi
  • utas meninggalkan CPU dan menghentikan eksekusi
  • utas tidak menghabiskan waktu CPU saat tidur

Saya tidak bisa mengerti mekanisme internal dan fundamental dari apa arti semua ini.

Saya mengerti bahwa ada sesuatu yang disebut scheduler yang bertanggung jawab untuk beralih antar utas.

Sumber tampaknya menunjukkan bahwa ini bervariasi berdasarkan OS (atau perangkat keras?) Dan sebagian besar utas diberikan 1ms - 60ms atau lebih untuk melakukan beberapa tindakan sebelum CPU beralih ke utas lainnya.

Tetapi ketika sebuah thread tertidur (misalnya, beberapa detik), bagaimana cara melanjutkannya? Saya kira timer terlibat, entah bagaimana, itu jam motherboard? Apakah ini terkait dengan laju jam CPU?

Dan bahkan jika timer terlibat, bagaimana CPU tahu kapan waktunya untuk memperhatikan utas lagi? Bukankah harus selalu memeriksa utas untuk melihat apakah sudah siap? Bukankah itu efektif polling dan karena itu jenis ini memakan waktu CPU?

Apakah tidur thread-bahasa khusus atau OS bertanggung jawab untuk itu atau itu hal yang spesifik CPU?

Bisakah seseorang menjelaskan hal ini kepada saya dengan penjelasan dasar tentang hal-hal seperti scheduler dan apa yang CPU lakukan selama semua ini?

Rowan Freeman
sumber
2
Membangkitkan thread tidur lagi bekerja dengan interupsi waktunya, biasanya dihasilkan oleh jam interupsi, yang merupakan komponen perangkat keras yang terpisah dari bagian inti CPU yang memproses instruksi. Itu menghindari kebutuhan untuk pemungutan suara. Mungkin penjelasan tentang Quora ini akan mengklarifikasi beberapa hal: quora.com/How-does-threading-work-at-CPU-level
Doc Brown
1
Kebanyakan JVM tidak benar-benar mengimplementasikan multi-threading: Yang mereka lakukan hanyalah menggunakan kemampuan multi-threading dari sistem operasi yang mendasarinya. Jika Anda benar-benar ingin tahu cara kerjanya, ada banyak buku tentang masalah desain sistem operasi.
Solomon Slow

Jawaban:

11

Ada jauh lebih banyak yang terlibat dalam menjalankan program daripada hanya kode dalam program itu.

Program apa pun yang berjalan dalam multi-proses OS berada di bawah kendali penjadwal OS , dan penjadwal tidak mempertahankan tabel eksplisit yang mengatakan proses apa yang sedang berjalan, mana yang sedang menunggu untuk dijalankan ketika siklus CPU tersedia, dan mana yang bahkan tidak mencoba lari (tidur). Penjadwal biasanya memberikan irisan waktu berukuran genap untuk proses tergantung pada prioritas dan riwayat eksekusi mereka. Pada akhirnya, loop ini digerakkan oleh interupsi perangkat keras, biasanya dihasilkan oleh osilator di papan utama.

Tidur selalu merupakan fitur yang didukung oleh bahasa pemrograman hanya karena lingkungan run-time di mana itu akan dijalankan mendukungnya. Suatu program normal tidak dapat menangguhkan dirinya sendiri , ia hanya dapat memberi tahu penjadwal bagaimana ia ingin diperlakukan - dan penjadwal itu sama sekali tidak berkewajiban atau bahkan selalu mampu memenuhi keinginan itu. Pikirkan laptop yang sedang ditutup dan memasuki mode hibernasi; osilator papan utama terus berdenyut, tetapi karena penjadwal tidak berjalan, tidak ada proses yang dapat berjalan tidak peduli seberapa tinggi prioritasnya.

Kilian Foth
sumber
Ini (umumnya) berlaku untuk proses, tetapi tidak selalu benar untuk utas, yang terkadang bergantung pada bahasa. Thread dapat diimplementasikan secara independen dari OS, dan dapat bersifat kooperatif atau preemptive. Misalnya Ruby memiliki "serat" (selain utas). Serat Ruby dijadwalkan secara kooperatif.
david25272
Benar, hanya utas asli yang berfungsi seperti ini. Utas hijau dijadwalkan oleh VM yang menjalankan program dalam bahasa yang dikompilasi dengan byte. Biasanya mereka digunakan ketika utas asli tidak tersedia, atau ketika menjalankan kode yang tidak benar utas-aman (VM kadang-kadang dapat memastikan bahwa semantik dari program multi-utas tetap benar dengan cara yang penjadwal OS tidak bisa).
Kilian Foth
7

Seperti yang disebutkan Doc Brown dalam komentar, interupsi adalah kuncinya, dan bukan hanya untuk tidur.

Interupsi adalah sinyal perangkat keras bahwa prosesor harus menghentikan apa yang dilakukannya dan menjalankan sepotong kode. Perangkat eksternal memicu interupsi ketika mereka membutuhkan perhatian prosesor: misalnya, ketika disk selesai membaca data, atau tombol telah ditekan, atau penghitung waktu mundur pada motherboard telah mencapai nol.

Kode penanganan interupsi umumnya sangat kecil dan sangat cepat. Misalnya, ketika disk menunjukkan blok telah disalin ke memori, OS mungkin hanya merekam fakta itu dalam daftar "blok siap" di suatu tempat dan kemudian kembali ke apa pun yang sedang dilakukannya. Anda tidak ingin CPU menghabiskan seluruh waktunya dalam kode penanganan interupsi dan tidak menjalankan kode pengguna.

Salah satu bagian dari kode interrupt-driven yang tidak selalu kecil adalah penjadwal. Ini dipicu oleh sinyal dari penghitung waktu mundur, dan memeriksa keadaan sistem setiap kali dijalankan. Ini biasanya akan mencakup proses identifikasi yang siap dijalankan (misalnya, karena blok yang mereka tunggu telah tiba di memori), serta yang sudah kehabisan waktu.

Jadi, ketika Anda menjalankan thread sleep, apa yang Anda lakukan adalah memberi tahu OS bahwa (1) Anda menyerahkan waktu Anda, dan (2) Anda tidak boleh dibangunkan lagi sampai waktu tertentu berlalu.

Setiap kali penjadwal berjalan, ia akan melihat utas Anda dan hanya menandainya sebagai "siap untuk dijalankan" jika waktu itu telah berlalu. Ini adalah polling, sejenisnya, tapi ini bukan polling "sibuk-loop" karena dipicu oleh interupsi. Ini juga tidak semahal itu: biasanya hanya ada seribu atau lebih utas yang berjalan sekaligus.

Ini juga harus memberi Anda gambaran mengapa waktu tidur tidak tepat: ketika utas Anda siap untuk berjalan, mungkin ada utas lain yang masih berjalan dan belum kehabisan waktu. Atau mungkin ada utas dengan prioritas lebih tinggi yang siap dijalankan.

kdgregory
sumber
Ini adalah cara kerja sistem operasi "modern". Dalam sistem operasi yang lebih lama, seperti Windows 3 atau Mac OS sebelum OS X proses harus menghasilkan () kontrol ke sistem operasi. Sayangnya, jika suatu program macet dalam satu lingkaran atau menemui jalan buntu, itu mungkin tidak akan pernah menghasilkan kontrol, dan seluruh sistem akan hang.
david25272
@ david25272 - Saya pikir saya akan menggunakan kata "lebih sederhana" daripada "lebih tua," karena ada sistem dari tahun 1960-an yang melakukan preemptive multitasking. Dan sementara memang benar bahwa multtasking kooperatif membutuhkan utas aktif untuk melakukan sesuatu untuk melepaskan kontrol prosesor (biasanya dengan membuat panggilan sistem pemblokiran, daripada hasil eksplisit), saya tidak percaya bahwa ada banyak programmer tujuan umum hari ini yang menggunakan OS dengan model threading kooperatif.
kdgregory