Saat menulis aplikasi multi-utas, salah satu masalah paling umum yang dialami adalah kebuntuan.
Pertanyaan saya kepada komunitas adalah:
Apa itu jalan buntu?
Bagaimana Anda mendeteksi mereka?
Apakah Anda menanganinya?
Dan akhirnya, bagaimana Anda mencegahnya terjadi?
multithreading
concurrency
locking
deadlock
bmurphy1976
sumber
sumber
Jawaban:
Sebuah kunci terjadi ketika beberapa proses mencoba untuk mengakses sumber daya yang sama pada waktu yang sama.
Satu proses hilang dan harus menunggu yang lain selesai.
Sebuah kebuntuan terjadi ketika proses tunggu masih berpegang pada sumber daya lain yang kebutuhan pertama sebelum dapat menyelesaikan.
Jadi, sebuah contoh:
Sumber daya A dan sumber daya B digunakan oleh proses X dan proses Y
Cara terbaik untuk menghindari kebuntuan adalah dengan menghindari proses melintas dengan cara ini. Kurangi kebutuhan untuk mengunci apa pun sebanyak yang Anda bisa.
Dalam basis data, hindari membuat banyak perubahan pada tabel yang berbeda dalam satu transaksi, hindari pemicu dan beralih ke optimis / kotor / nolock membaca sebanyak mungkin.
sumber
Biarkan saya menjelaskan contoh dunia nyata (tidak benar-benar nyata) untuk situasi jalan buntu dari film-film kejahatan. Bayangkan seorang penjahat menyandera dan melawan itu, seorang polisi juga menyandera seorang teman penjahat. Dalam kasus ini, penjahat tidak akan membiarkan sandera pergi jika polisi tidak akan membiarkan temannya melepaskannya. Juga polisi tidak akan membiarkan teman penjahat melepaskan, kecuali penjahat melepaskan sandera. Ini adalah situasi yang tak dapat dipercaya yang tak ada habisnya, karena kedua belah pihak bersikeras langkah pertama dari satu sama lain.
Criminal & Cop Scene
Jadi sederhananya, ketika dua utas membutuhkan dua sumber daya yang berbeda dan masing-masing dari mereka memiliki kunci sumber daya yang dibutuhkan oleh yang lain, itu adalah jalan buntu.
Penjelasan Tingkat Tinggi Kebuntuan Lain: Patah Hati
Anda berkencan dengan seorang gadis dan satu hari setelah pertengkaran, kedua belah pihak hancur hati satu sama lain dan menunggu panggilan saya-maaf-dan-saya-tidak terjawab . Dalam situasi ini, kedua belah pihak ingin berkomunikasi satu sama lain jika dan hanya jika salah satu dari mereka menerima panggilan maaf dari yang lain. Karena masing-masing tidak akan memulai komunikasi dan menunggu dalam keadaan pasif, keduanya akan menunggu yang lain untuk memulai komunikasi yang berakhir dalam situasi jalan buntu.
sumber
Kebuntuan hanya akan terjadi ketika Anda memiliki dua kunci atau lebih yang dapat diperoleh pada saat yang sama dan mereka diambil dalam urutan yang berbeda.
Cara untuk menghindari kebuntuan adalah:
sumber
Untuk mendefinisikan kebuntuan, pertama saya akan mendefinisikan proses.
Proses : Seperti yang kita tahu proses tidak lain adalah
program
eksekusi.Sumberdaya : Untuk menjalankan suatu proses program dibutuhkan beberapa sumber daya. Kategori sumber daya dapat meliputi memori, printer, CPU, file terbuka, tape drive, CD-ROM, dll.
Jalan buntu : Deadlock adalah situasi atau kondisi ketika dua proses atau lebih memegang beberapa sumber daya dan mencoba untuk memperoleh beberapa sumber daya lebih banyak, dan mereka tidak dapat melepaskan sumber daya sampai mereka menyelesaikan eksekusi di sana.
Kondisi atau situasi jalan buntu
Dalam diagram di atas ada dua proses P1 dan p2 dan ada dua sumber daya R1 dan R2 .
Sumber daya R1 dialokasikan untuk memproses P1 dan sumber daya R2 dialokasikan untuk memproses p2 . Untuk menyelesaikan eksekusi proses P1 perlu resource R2 , jadi P1 meminta R2 , tetapi R2 sudah dialokasikan untuk P2 .
Dengan cara yang sama, Proses P2 untuk menyelesaikan eksekusi membutuhkan R1 , tetapi R1 sudah dialokasikan untuk P1 .
kedua proses tidak dapat melepaskan sumber daya mereka sampai dan kecuali mereka menyelesaikan eksekusi mereka. Jadi keduanya menunggu sumber daya lain dan mereka akan menunggu selamanya. Jadi ini DEADLOCK Kondisi .
Agar kebuntuan terjadi, empat kondisi harus benar.
dan semua kondisi ini terpenuhi dalam diagram di atas.
sumber
Kebuntuan terjadi ketika utas sedang menunggu sesuatu yang tidak pernah terjadi.
Biasanya, ini terjadi ketika utas menunggu pada mutex atau semaphore yang tidak pernah dirilis oleh pemilik sebelumnya.
Ini juga sering terjadi ketika Anda memiliki situasi yang melibatkan dua utas dan dua kunci seperti ini:
Anda biasanya mendeteksi mereka karena hal-hal yang Anda harapkan terjadi tidak pernah dilakukan, atau aplikasi hang sepenuhnya.
sumber
Anda dapat melihat artikel yang luar biasa ini , di bawah bagian Deadlock . Itu ada di C # tetapi idenya masih sama untuk platform lain. Saya kutip di sini agar mudah dibaca
sumber
Deadlock adalah masalah umum dalam masalah multiprocessing / multiprogramming di OS. Katakanlah ada dua proses P1, P2 dan dua sumber daya yang dapat dibagikan secara global R1, R2 dan di bagian kritis kedua sumber daya perlu diakses
Awalnya, OS menetapkan R1 untuk memproses P1 dan R2 untuk memproses P2. Karena kedua proses berjalan secara bersamaan, mereka mungkin mulai mengeksekusi kode mereka tetapi MASALAH muncul ketika suatu proses menyentuh bagian kritis. Jadi proses R1 akan menunggu proses P2 untuk merilis R2 dan sebaliknya ... Jadi mereka akan menunggu selamanya (DEADLOCK CONDITION).
ANALOGI kecil ...
sumber
Kebuntuan terjadi ketika dua utas meminta kunci yang mencegah salah satu dari mereka berkembang. Cara terbaik untuk menghindarinya adalah dengan pengembangan yang cermat. Banyak sistem tertanam melindungi dari mereka dengan menggunakan pengawas waktu (pengatur waktu yang me-reset sistem setiap kali jika hang untuk jangka waktu tertentu).
sumber
Kebuntuan terjadi ketika ada rantai melingkar benang atau proses yang masing-masing memegang sumber daya yang terkunci dan mencoba untuk mengunci sumber daya yang dimiliki oleh elemen berikutnya dalam rantai. Misalnya, dua utas yang masing-masing menahan kunci A dan kunci B, dan keduanya berusaha mendapatkan kunci lainnya.
sumber
Program klasik dan sangat sederhana untuk memahami situasi Deadlock : -
Ketika utas utama memanggil Lazy.main, ia memeriksa apakah kelas Lazy telah diinisialisasi dan mulai menginisialisasi kelas. Utas utama sekarang menyetel inisialisasi ke false, membuat dan memulai utas latar belakang yang metodenya set diinisialisasi menjadi true, dan menunggu utas latar belakang selesai.
Kali ini, kelas saat ini sedang diinisialisasi oleh utas lainnya. Dalam keadaan ini, utas saat ini, yang merupakan utas latar belakang, menunggu objek Class hingga inisialisasi selesai. Sayangnya, utas yang sedang melakukan inisialisasi, utas utama, sedang menunggu utas latar belakang selesai. Karena dua utas sekarang menunggu satu sama lain, program ini DIHADAPI.
sumber
Kebuntuan adalah keadaan sistem di mana tidak ada proses / utas tunggal yang mampu melakukan suatu tindakan. Seperti disebutkan oleh orang lain, kebuntuan biasanya merupakan hasil dari situasi di mana setiap proses / utas ingin mendapatkan kunci ke sumber daya yang sudah dikunci oleh proses / utas lain (atau bahkan sama).
Ada berbagai metode untuk menemukannya dan menghindarinya. Seseorang berpikir sangat keras dan / atau mencoba banyak hal. Namun, berurusan dengan paralelisme sangat sulit dan sebagian besar (jika tidak semua) orang tidak akan dapat sepenuhnya menghindari masalah.
Beberapa metode yang lebih formal dapat bermanfaat jika Anda serius berurusan dengan masalah seperti ini. Metode paling praktis yang saya sadari adalah menggunakan pendekatan teori proses. Di sini Anda membuat model sistem Anda dalam beberapa bahasa proses (mis. CCS, CSP, ACP, mCRL2, LOTOS) dan menggunakan alat yang tersedia untuk (model-) memeriksa kebuntuan (dan mungkin beberapa properti lainnya juga). Contoh toolset untuk digunakan adalah FDR, mCRL2, CADP dan Uppaal. Beberapa jiwa pemberani bahkan mungkin membuktikan sistem mereka bebas dari kebuntuan dengan menggunakan metode simbolik murni (pembuktian teorema; cari Owicki-Gries).
Namun, metode formal ini biasanya memang memerlukan beberapa upaya (misalnya mempelajari dasar-dasar teori proses). Tapi saya kira itu hanyalah konsekuensi dari kenyataan bahwa masalah ini sulit.
sumber
Kebuntuan adalah situasi yang terjadi ketika jumlah sumber daya yang tersedia lebih sedikit karena diminta oleh proses yang berbeda. Ini berarti bahwa ketika jumlah sumber daya yang tersedia menjadi kurang dari yang diminta oleh pengguna maka pada saat itu proses berjalan dalam kondisi menunggu. Beberapa kali menunggu meningkat lebih banyak dan tidak ada kesempatan untuk memeriksa masalah kekurangan sumber daya kemudian situasi ini dikenal sebagai jalan buntu. Sebenarnya, kebuntuan adalah masalah utama bagi kami dan itu terjadi hanya dalam sistem operasi multitasking .deadlock tidak dapat terjadi dalam sistem operasi penugasan tunggal karena semua sumber daya hadir hanya untuk tugas yang sedang berjalan ......
sumber
Di atas beberapa penjelasan bagus. Semoga ini juga berguna: https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html
Dalam database, ketika suatu sesi (misalnya ora) menginginkan sumber daya dipegang oleh sesi lain (misalnya data), tetapi sesi (data) itu juga menginginkan sumber daya yang dipegang oleh sesi pertama (ora). Mungkin ada lebih dari 2 sesi yang terlibat, tetapi idenya akan sama. Sebenarnya, kebuntuan mencegah beberapa transaksi terus bekerja. Sebagai contoh: Misalkan, ORA-DATA memegang kunci A dan meminta kunci B Dan SKU memegang kunci B dan meminta kunci A.
Terima kasih,
sumber
Kebuntuan terjadi ketika utas sedang menunggu utas lainnya selesai dan sebaliknya.
Bagaimana cara menghindarinya?
- Hindari Kunci Bertumpuk
- Hindari Kunci Tidak Perlu
- Gunakan utas gabung ()
Bagaimana Anda mendeteksinya?
jalankan perintah ini di cmd:
referensi : geeksforgeeks
sumber
Kebuntuan tidak terjadi begitu saja dengan kunci, meskipun itulah penyebab paling sering. Di C ++, Anda bisa membuat kebuntuan dengan dua utas dan tanpa kunci dengan hanya meminta setiap utas bergabung () pada objek std :: utas untuk yang lainnya.
sumber
Kontrol concurrency berbasis kunci
Menggunakan penguncian untuk mengontrol akses ke sumber daya bersama rentan terhadap kebuntuan, dan penjadwal transaksi sendiri tidak dapat mencegah kejadiannya.
Misalnya, sistem basis data relasional menggunakan berbagai kunci untuk menjamin properti ACID transaksi .
Apa pun sistem basis data relasional yang Anda gunakan, kunci akan selalu diperoleh saat memodifikasi (misalnya,
UPDATE
atauDELETE
) catatan tabel tertentu. Tanpa mengunci baris yang dimodifikasi oleh transaksi yang sedang berjalan, Atomicity akan dikompromikan .Apa itu jalan buntu
Seperti yang saya jelaskan dalam artikel ini , kebuntuan terjadi ketika dua transaksi bersamaan tidak dapat membuat kemajuan karena masing-masing menunggu yang lain untuk melepaskan kunci, seperti yang diilustrasikan dalam diagram berikut.
Karena kedua transaksi berada dalam fase akuisisi kunci, tidak ada yang melepaskan kunci sebelum memperoleh yang berikutnya.
Sembuh dari situasi jalan buntu
Jika Anda menggunakan algoritma Kontrol Konkurensi yang bergantung pada kunci, maka selalu ada risiko berjalan dalam situasi jalan buntu. Kebuntuan dapat terjadi di lingkungan konkurensi apa pun, tidak hanya dalam sistem basis data.
Misalnya, program multithreading dapat menemui jalan buntu jika dua atau lebih utas menunggu pada kunci yang sebelumnya diperoleh sehingga tidak ada utas yang dapat membuat kemajuan. Jika ini terjadi pada aplikasi Java, JVM tidak bisa memaksa Thread untuk menghentikan eksekusi dan melepaskan kunci-kuncinya.
Bahkan jika
Thread
kelas mengekspos suatustop
metode, metode itu sudah tidak digunakan lagi sejak Java 1.1 karena dapat menyebabkan objek dibiarkan dalam keadaan tidak konsisten setelah thread dihentikan. Sebaliknya, Java mendefinisikaninterrupt
metode, yang bertindak sebagai petunjuk sebagai utas yang terputus dapat dengan mudah mengabaikan gangguan dan melanjutkan eksekusi.Untuk alasan ini, aplikasi Java tidak dapat pulih dari situasi deadlock, dan merupakan tanggung jawab pengembang aplikasi untuk memesan permintaan akuisisi kunci sedemikian rupa sehingga deadlock tidak pernah terjadi.
Namun, sistem basis data tidak dapat memberlakukan perintah akuisisi kunci yang diberikan karena tidak mungkin untuk meramalkan kunci lain yang ingin diperoleh transaksi tertentu. Mempertahankan urutan kunci menjadi tanggung jawab lapisan akses data, dan database hanya dapat membantu memulihkan dari situasi deadlock.
Mesin basis data menjalankan proses terpisah yang memindai grafik konflik saat ini untuk siklus kunci-tunggu (yang disebabkan oleh deadlock). Ketika sebuah siklus terdeteksi, mesin basis data mengambil satu transaksi dan membatalkannya, menyebabkan kunci-nya dilepaskan, sehingga transaksi lainnya dapat membuat kemajuan.
Berbeda dengan JVM, transaksi basis data dirancang sebagai unit kerja atom. Oleh karena itu, rollback membuat database dalam keadaan konsisten.
Untuk detail lebih lanjut tentang topik ini, lihat artikel ini juga.
sumber
Mutex pada dasarnya adalah kunci, menyediakan akses yang dilindungi ke sumber daya bersama. Di Linux, tipe data thread mutex adalah pthread_mutex_t. Sebelum digunakan, inisialisasi.
Untuk mengakses sumber daya bersama, Anda harus mengunci mutex. Jika mutex sudah di kunci, panggilan akan memblokir utas sampai mutex dibuka. Setelah menyelesaikan kunjungan ke sumber daya bersama, Anda harus membuka kuncinya.
Secara keseluruhan, ada beberapa prinsip dasar yang tidak tertulis:
Dapatkan kunci sebelum menggunakan sumber daya bersama.
Memegang kunci sesingkat mungkin.
Lepaskan kunci jika utas mengembalikan kesalahan.
sumber