Apa sebenarnya "spin-locks" itu?


108

Saya selalu bertanya-tanya apa itu: setiap kali saya mendengarnya, gambar perangkat seperti flywheel yang futuristik menari (berputar?) Di benak saya ...

Apakah mereka?

Jawaban:


125

Saat Anda menggunakan kunci biasa (mutex, bagian kritis, dll.), Sistem operasi menempatkan utas Anda dalam status WAIT dan mendahului dengan menjadwalkan utas lain pada inti yang sama. Ini memiliki penalti kinerja jika waktu tunggu sangat singkat, karena utas Anda sekarang harus menunggu preemption untuk menerima waktu CPU lagi.

Selain itu, objek kernel tidak tersedia di setiap status kernel, seperti di penangan interupsi atau saat paging tidak tersedia, dll.

Spinlock tidak menyebabkan preemption tetapi menunggu dalam satu putaran ("spin") sampai inti lainnya melepaskan kunci. Ini mencegah utas kehilangan kuantumnya dan melanjutkan segera setelah kunci dilepaskan. Mekanisme sederhana dari spinlock memungkinkan kernel untuk menggunakannya di hampir semua kondisi.

Itulah mengapa pada mesin inti tunggal, spinlock hanyalah "menonaktifkan interupsi" atau "meningkatkan IRQL" yang mencegah penjadwalan thread sepenuhnya.

Spinlock pada akhirnya memungkinkan kernel untuk menghindari "Big Kernel Lock" (kunci yang diperoleh saat inti memasuki kernel dan dilepaskan saat keluar) dan memiliki penguncian granular atas kernel primitif, menyebabkan multi-pemrosesan yang lebih baik pada mesin multi-core sehingga kinerja yang lebih baik.

EDIT : Sebuah pertanyaan muncul: "Apakah itu berarti saya harus menggunakan spinlock sedapat mungkin?" dan saya akan mencoba menjawabnya:

Seperti yang saya sebutkan, Spinlock hanya berguna di tempat-tempat di mana waktu tunggu yang diantisipasi lebih pendek daripada kuantum (baca: milidetik) dan preemption tidak masuk akal (misalnya objek kernel tidak tersedia).

Jika waktu tunggu tidak diketahui, atau jika Anda dalam mode pengguna, Spinlock tidak efisien. Anda menghabiskan 100% waktu CPU pada inti tunggu sambil memeriksa apakah spinlock tersedia. Anda mencegah utas lain berjalan pada inti itu hingga kuantum Anda kedaluwarsa. Skenario ini hanya layak untuk ledakan singkat pada tingkat kernel dan tidak mungkin merupakan opsi untuk aplikasi mode pengguna.

Berikut adalah pertanyaan tentang SO yang menjawab bahwa: Spinlocks, Seberapa Berguna Apakah Mereka?


apakah itu berarti saya harus melakukan spin-locks (bukan mutex, critical-section, dll.) jika memungkinkan?

1
seseorang tolong perbaiki saya jika saya salah, tetapi spinlock tidak menonaktifkan preemption (mis. penjadwalan ulang). karena alasan sederhana bahwa, jika spinlock sedang menunggu sumber daya dikunci oleh proses lain, maka proses kedua tersebut harus diberi kesempatan untuk berjalan dan membebaskan sumber daya. atau, menjalankan proses kedua membutuhkan preempting dari proses pertama (pemintalan).
pengguna1284631

apa yang dilakukan spinlock adalah bahwa ia tidak mengubah status proses dari TASK_RUNNING menjadi TASK_INTERRUPTIBLE (yang merupakan kondisi tidur) dan, karenanya, tidak menyimpan segala sesuatu tentang proses itu (memori, cache, dan sebagainya). sebaliknya, proses pemintalan diawali, tetapi tidak pernah berhenti dari proses "segera dijadwalkan": itu disimpan dalam memori dan proses lainnya secara teratur dijalankan sampai salah satu dari mereka membebaskan sumber daya yang menunggu pemintal: pada saat itu, spinlock hanya kembali dan proses pemintalan dapat dilanjutkan. itu menunggu dalam keadaan selalu TASK_RUNNING.
pengguna1284631

1
Anda benar tentang itu (lihat juga ini: linuxjournal.com/article/5833 ), tetapi faktanya adalah mengunci sumber daya dan menonaktifkan interupsi, meskipun berguna untuk dilakukan bersama, adalah konsep yang tidak berhubungan. Anda pada dasarnya ingin memastikan bahwa Anda tidak menggunakan sumber daya yang ditemukan dalam keadaan tidak konsisten, dan inilah alasan Anda menguji kuncinya. menonaktifkan interupsi (juga preemption) memastikan bahwa ya, tidak ada yang akan mengacaukan resurce Anda saat Anda mengatasinya. Namun, untuk itu, Anda harus yakin bahwa resource tersebut gratis saat Anda mendapatkannya.
pengguna1284631

1
(kemudian nonaktifkan interupsi hanya untuk memastikan bahwa tidak ada tugas lain yang menghalangi Anda dan mengacaukan sumber daya). pada UP (uni-processor), ini selalu terjadi: spinlock pertama (dan yang berikutnya) diberikan begitu saja, interupsi (yaitu preemption) dinonaktifkan, dan tugas yang menggunakan sumber daya tidak pernah didahului: ia melakukan semua tugasnya. pekerjaan dengan sumber daya, lalu aktifkan interupsi (dan, dengan demikian, preemption). ketika preemption diaktifkan, maka sumber daya sudah gratis. pada dasarnya, di UP, tidak ada pertikaian spinlock dan tidak ada menunggu . di SMP mungkin saja.
pengguna1284631

25

Misalnya sumber daya dilindungi oleh kunci, utas yang menginginkan akses ke sumber daya perlu mendapatkan kunci terlebih dahulu. Jika kunci tidak tersedia, utas mungkin berulang kali memeriksa apakah kunci telah dibebaskan. Selama waktu ini, utas sibuk menunggu, memeriksa kunci, menggunakan CPU, tetapi tidak melakukan pekerjaan yang berguna. Kunci seperti itu disebut kunci putar.


2
Jawaban bagus! +1
Jayesh Bhoi

18

Ini adalah perulangan yang tepat yang terus berjalan sampai kondisi tertentu terpenuhi:

while(cantGoOn) {};

1
And / or while (cantGoOn) {sleep (0)};
Jiminion

@Jiminion jika Anda meletakkannya sleep(0)akan mendahului utas, mematikan tujuan menggunakan spinlock di tempat pertama. jika Anda perlu menyerah ke utas lain, Anda harus menggunakan kunci biasa. (Saya tahu komentar Anda sudah sangat tua tetapi ingin mencegah orang lain melihat ini sebagai saran).
Sedat Kapanoglu

"Nilai nol menyebabkan utas melepaskan sisa potongan waktunya ke utas lain yang siap dijalankan. Jika tidak ada utas lain yang siap dijalankan, fungsi segera kembali, dan utas melanjutkan eksekusi."
Jiminion


5

Ini adalah jenis kunci yang sibuk menunggu

Ini dianggap sebagai anti-pola, kecuali untuk pemrograman driver tingkat sangat rendah (di mana dapat terjadi bahwa memanggil fungsi menunggu yang "tepat" memiliki lebih banyak overhead daripada hanya penguncian sibuk untuk beberapa siklus).

Lihat misalnya Spinlocks di kernel Linux .


3

SpinLocks adalah yang di mana utas menunggu sampai kunci tersedia. Ini biasanya akan digunakan untuk menghindari overhead dalam memperoleh objek kernel saat ada cakupan untuk memperoleh objek kernel dalam beberapa periode waktu singkat.

Ex:

While(SpinCount-- && Kernel Object is not free)
{}

try acquiring Kernel object

3

Anda ingin menggunakan spinlock jika menurut Anda lebih murah untuk memasuki loop tunggu yang sibuk dan mengumpulkan sumber daya daripada memblokir saat sumber daya terkunci.

Pemintalan dapat bermanfaat saat kunci berbutir halus dan jumlahnya besar (misalnya, kunci per node dalam daftar tertaut) serta saat waktu penahanan kunci selalu sangat singkat. Secara umum, sambil memegang kunci putar, seseorang harus menghindari pemblokiran, memanggil apa pun yang mungkin diblokir, memegang lebih dari satu kunci putar sekaligus, membuat panggilan yang dikirim secara dinamis (antarmuka dan virtual), membuat panggilan yang dikirim secara statis ke kode apa pun yang tidak dilakukan seseorang ' t memiliki, atau mengalokasikan memori.

Penting juga untuk dicatat bahwa SpinLock adalah tipe nilai, untuk alasan kinerja. Dengan demikian, seseorang harus sangat berhati-hati untuk tidak secara tidak sengaja menyalin instance SpinLock, karena kedua instance (asli dan salinannya) kemudian akan sepenuhnya independen satu sama lain, yang kemungkinan akan menyebabkan perilaku aplikasi yang salah. Jika instance SpinLock harus diedarkan, itu harus diteruskan dengan referensi, bukan dengan nilai.


1

Singkatnya, spinlock menggunakan atomic Compare and Swap (CAS) atau instruksi seperti test-and-set untuk mengimplementasikan lock free, tunggu idiom thread safe gratis. Struktur seperti itu berskala baik di mesin multi-inti.


Secara definisi, spinlock tidak digunakan untuk mengimplementasikan kunci apa pun yang bebas atau menunggu bebas.
rdb

0

Ini adalah lingkaran yang berputar sampai suatu kondisi terpenuhi.


0

Ya, inti dari spin locks (vs bagian kritis tradisional, dll) adalah bahwa mereka menawarkan kinerja yang lebih baik dalam beberapa keadaan (sistem multicore ..), karena mereka tidak segera menghasilkan sisa kuantum utas.


0

Spinlock, adalah jenis kunci, yang tidak dapat diblokir & tidak dapat tidur. Setiap utas yang ingin memperoleh spinlock untuk sumber daya bersama atau kritis akan terus berputar, menyia-nyiakan siklus pemrosesan CPU hingga memperoleh kunci untuk sumber daya yang ditentukan. Setelah spinlock diperoleh, ia mencoba menyelesaikan pekerjaan di kuantumnya dan kemudian melepaskan sumber daya masing-masing. Spinlock adalah jenis kunci dengan prioritas tertinggi, dapat dikatakan, ini adalah jenis kunci non-preemptive.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.