Apa itu pertentangan utas?


121

Bisakah seseorang menjelaskan dengan sederhana apa itu pertentangan utas?

Saya telah mencarinya di Google, tetapi tidak dapat menemukan penjelasan sederhana.


10
Jadi tuliskan apa yang Anda pikirkan secara samar-samar, sehingga kami dapat melihat di mana Anda mungkin pergi, atau pemahaman Anda mungkin benar.
James Black

Jawaban:


88

Intinya thread contention adalah suatu kondisi di mana satu thread menunggu kunci / objek yang sedang ditahan oleh thread lain. Oleh karena itu, utas tunggu ini tidak dapat menggunakan objek tersebut hingga utas lainnya telah membuka kunci objek tersebut.


53
Jawaban ini tidak lengkap (seperti kebanyakan jawaban lainnya). Meskipun kunci adalah salah satu jenis hal yang dapat diperdebatkan, kunci bukanlah satu-satunya hal yang seperti itu. Mungkin ada pertikaian untuk sumber daya tanpa kunci juga. (Misalnya, jika dua utas terus menambah bilangan bulat yang sama secara atomis, mereka mungkin mengalami perselisihan karena cache ping-ponging. Tidak ada kunci yang terlibat.)
David Schwartz

Dalam kasus Kunci Penerjemah Global (GIL) seperti di CPython, di mana sebuah utas harus selalu memperoleh GIL, oleh karena itu beberapa utas yang berjalan dalam proses yang sama akan diperdebatkan secara default.
Acumenus

Saya pikir Anda telah menjelaskannya dalam istilah Deadlock tetapi sangat jauh berbeda dengan Deadlock.
Harshit Gupta

185

Beberapa jawaban tampaknya berfokus pada pertengkaran kunci, tetapi gembok bukanlah satu-satunya sumber daya yang dapat dialami pertengkaran. Perselisihan adalah ketika dua utas mencoba mengakses sumber daya yang sama atau sumber daya terkait sedemikian rupa sehingga setidaknya salah satu utas bersaing berjalan lebih lambat daripada jika utas lainnya tidak berjalan.

Contoh pertengkaran yang paling jelas adalah tentang gembok. Jika utas A memiliki kunci dan utas B ingin mendapatkan kunci yang sama, utas B harus menunggu hingga utas A melepaskan kunci.

Sekarang, ini khusus platform, tetapi utas mungkin mengalami pelambatan meskipun tidak pernah harus menunggu utas lain melepaskan kuncinya! Ini karena kunci melindungi beberapa jenis data, dan data itu sendiri akan sering diperdebatkan juga.

Misalnya, pertimbangkan utas yang memperoleh kunci, memodifikasi objek, lalu melepaskan kunci dan melakukan beberapa hal lainnya. Jika dua utas melakukan ini, bahkan jika mereka tidak pernah memperebutkan kunci, utas mungkin berjalan jauh lebih lambat daripada jika hanya satu utas yang berjalan.

Mengapa? Katakanlah setiap utas berjalan pada intinya sendiri pada CPU x86 modern dan inti tidak berbagi cache L2. Dengan hanya satu utas, objek dapat tetap berada di cache L2 hampir sepanjang waktu. Dengan kedua utas berjalan, setiap kali satu utas memodifikasi objek, utas lainnya akan menemukan data tidak dalam cache L2-nya karena CPU lain membatalkan baris cache. Pada Pentium D, misalnya, ini akan menyebabkan kode berjalan pada kecepatan FSB, yang jauh lebih rendah dari kecepatan cache L2.

Karena perselisihan dapat terjadi bahkan jika gembok itu sendiri tidak diperebutkan, perselisihan juga dapat terjadi bila tidak ada gembok. Misalnya, CPU Anda mendukung penambahan atom dari variabel 32-bit. Jika satu utas terus menambah dan mengurangi variabel, variabel akan menjadi panas di cache hampir sepanjang waktu. Jika dua utas melakukannya, cache mereka akan memperebutkan kepemilikan memori yang menyimpan variabel itu, dan banyak akses akan lebih lambat karena protokol koherensi cache beroperasi untuk mengamankan setiap kepemilikan inti dari baris cache.

Ironisnya, gembok biasanya mengurangi pertengkaran. Mengapa? Karena tanpa kunci, dua utas dapat beroperasi pada objek atau koleksi yang sama dan menyebabkan banyak pertikaian (misalnya, ada antrian bebas kunci). Locks akan cenderung untuk membatalkan thread yang bersaing, memungkinkan thread yang tidak bersaing untuk dijalankan. Jika utas A memegang kunci dan utas B menginginkan kunci yang sama, implementasi dapat menjalankan utas C sebagai gantinya. Jika utas C tidak membutuhkan kunci itu, maka perselisihan di masa mendatang antara utas A dan B dapat dihindari untuk sementara. (Tentu saja, ini mengasumsikan ada utas lain yang dapat berjalan. Ini tidak akan membantu jika satu-satunya cara sistem secara keseluruhan dapat membuat kemajuan yang berguna adalah dengan menjalankan utas yang bersaing.)


4
+1 Juga, hanya untuk membuat ini eksplisit, dua variabel yang diperebutkan oleh dua inti bahkan tidak perlu menjadi variabel yang sama untuk menyebabkan perselisihan, mereka hanya harus disimpan dalam memori di baris cache yang sama. Struktur bantalan dan / atau struktur penyelarasan ke memori dapat membantu menghindari bentuk pertengkaran ini.
Rob_before_edits

1
@David tolong bantu untuk memahami paragraf terakhir dari jawaban Anda secara lebih detail
Pelajar

4
@Naroji Ajukan pertanyaan tentang itu.
David Schwartz

@DavidSchwartz, Apakah Anda seorang programmer C?
Pacerier

@Perier C ++ kebanyakan.
David Schwartz

19

Dari sini :

Perselisihan terjadi saat utas menunggu sumber daya yang tidak tersedia; itu memperlambat eksekusi kode Anda, tetapi dapat hilang seiring waktu.

Kebuntuan terjadi saat utas menunggu sumber daya yang dikunci utas kedua, dan utas kedua menunggu sumber daya yang dikunci utas pertama. Lebih dari dua utas bisa terlibat dalam kebuntuan. Kebuntuan tidak pernah terpecahkan dengan sendirinya. Ini sering menyebabkan seluruh aplikasi, atau bagian yang mengalami kebuntuan, terhenti.


Ini juga menjelaskan perbedaan antara thread Contention dan Deadlock
Sankalp

3

Saya pikir harus ada klarifikasi dari OP tentang latar belakang pertanyaan - saya dapat memikirkan 2 jawaban (meskipun saya yakin ada tambahan untuk daftar ini):

  1. jika Anda mengacu pada "konsep" umum dari pertengkaran utas dan bagaimana hal itu dapat muncul dengan sendirinya dalam aplikasi, saya tunduk pada jawaban rinci @ DavidSchwartz di atas.

  2. Ada juga Penghitung Kinerja '.NET CLR Locks and Threads: Total # of Contentions'. Seperti yang diambil dari deskripsi PerfMon untuk penghitung ini, itu didefinisikan sebagai:

    Penghitung ini menampilkan total berapa kali utas di CLR mencoba memperoleh kunci terkelola namun tidak berhasil. Kunci yang dikelola dapat diperoleh dengan berbagai cara; dengan pernyataan "kunci" di C # atau dengan memanggil System.Monitor.Enter atau dengan menggunakan atribut kustom MethodImplOptions.Synchronized.

... dan saya yakin orang lain untuk OS dan kerangka aplikasi lain.


2

Anda memiliki 2 utas. Thread A dan Thread B, Anda juga memiliki objek C.

A sedang mengakses objek C, dan telah mengunci objek tersebut. B perlu mengakses objek C, tetapi tidak dapat melakukannya hingga A melepaskan kunci pada objek C.


1

Kata lain mungkin konkurensi. Ini hanyalah gagasan tentang dua atau lebih utas yang mencoba menggunakan sumber daya yang sama.


1

Bagi saya perselisihan adalah kompetisi antara 2 atau lebih utas atas sumber daya bersama. Sumber daya dapat berupa kunci, penghitung, dll. Kompetisi berarti "siapa yang mendapatkan lebih dulu". Semakin banyak utas semakin banyak pertikaian. Semakin sering akses ke sumber daya semakin banyak pertengkaran.


1

Bayangkan skenario berikut ini. Anda sedang mempersiapkan ujian terakhir besok dan merasa sedikit lapar. Jadi, Anda memberi adik Anda sepuluh dolar dan memintanya membelikan pizza untuk Anda. Dalam hal ini, Anda adalah utas utama dan saudara Anda adalah utas anak. Setelah pesanan Anda diberikan, Anda dan saudara Anda akan melakukan pekerjaan mereka secara bersamaan (yaitu, belajar dan membeli pizza). Sekarang, kami memiliki dua kasus untuk dipertimbangkan. Pertama, kakakmu membawakan pizzamu kembali dan berhenti saat kamu belajar. Dalam hal ini, Anda bisa berhenti belajar dan menikmati pizza. Kedua, Anda menyelesaikan studi Anda lebih awal dan tidur (yaitu, tugas Anda hari ini - belajar untuk ujian akhir besok - selesai) sebelum pizza tersedia. Tentu saja, Anda tidak bisa tidur; jika tidak, Anda tidak akan punya kesempatan untuk makan pizza.

Seperti pada contoh, kedua kasus tersebut memberi makna persaingan.


0

Pertentangan utas juga dipengaruhi oleh operasi I / O. Contoh ketika Thread menunggu file dibaca dapat dianggap sebagai pertengkaran. Gunakan port penyelesaian I / O sebagai solusi.


0

Pertikaian kunci terjadi saat utas mencoba mendapatkan kunci ke objek yang sudah diperoleh utas lain *. Hingga objek dilepaskan, utas akan diblokir (dengan kata lain, berada dalam status Menunggu). Dalam beberapa kasus, ini dapat menyebabkan apa yang disebut eksekusi serial yang secara negatif mempengaruhi aplikasi.

dari dokumentasi dotTrace

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.