Apakah ada cara masalah ini dapat mengambil manfaat dari solusi dengan beberapa utas, bukan satu utas?
Dalam sebuah wawancara, saya diminta untuk memecahkan masalah menggunakan beberapa utas. Tampak bagi saya bahwa banyak utas tidak menguntungkan.
Inilah masalahnya:
Anda diberi paragraf, yang berisi n jumlah kata, Anda diberikan m utas. Yang perlu Anda lakukan adalah, setiap utas harus mencetak satu kata dan memberikan kontrol ke utas berikutnya, dengan cara ini setiap utas akan terus mencetak satu kata, jika ada utas terakhir, ia harus mengaktifkan utas pertama. Pencetakan akan diulang sampai semua kata dicetak dalam paragraf. Akhirnya semua utas harus keluar dengan anggun. Jenis sinkronisasi apa yang akan digunakan?
Saya sangat merasa kami tidak dapat memanfaatkan utas di sini, tetapi percaya pewawancara sedang mencoba mengukur kemampuan sinkronisasi saya. Apakah saya melewatkan sesuatu dalam masalah ini yang akan membuat banyak utas bernilai?
Tidak perlu kode, cukup masukkan beberapa pemikiran. Saya akan menerapkannya sendiri.
sumber
Jawaban:
Kedengarannya bagi saya seperti mereka memimpin Anda menuju solusi semafor. Semaphores digunakan untuk memberi sinyal utas lain bahwa giliran mereka. Mereka digunakan jauh lebih jarang daripada mutex, yang saya kira adalah mengapa mereka pikir itu pertanyaan wawancara yang bagus. Itu juga mengapa contoh itu tampaknya dibuat-buat.
Pada dasarnya, Anda akan membuat
m
semaphores. Setiap utasx
menunggu di semaphorex
kemudian memposting ke semaphorex+1
setelah melakukan tugasnya. Dalam pseudocode:sumber
Menurut pendapat saya, ini adalah pertanyaan wawancara yang luar biasa - setidaknya dengan asumsi (1) kandidat diharapkan memiliki pengetahuan yang mendalam tentang threading, dan (2) pewawancara juga memiliki pengetahuan yang mendalam dan menggunakan pertanyaan untuk menyelidiki kandidat. Selalu mungkin pewawancara mencari jawaban spesifik dan sempit, tetapi pewawancara yang kompeten harus mencari yang berikut:
Poin terakhir ini, menurut saya, yang paling penting. Sekali lagi, berdasarkan pengalaman saya, secara eksponensial menjadi lebih sulit untuk men-debug kode berulir jika threading dicampur dengan logika aplikasi (lihat saja semua pertanyaan Swing di atas pada SO untuk contoh). Saya percaya bahwa kode multi-thread terbaik ditulis sebagai kode single-threaded mandiri, dengan handoff yang jelas.
Dengan mengingat hal ini, pendekatan saya adalah memberi masing-masing utas dua antrian: satu untuk input, satu untuk output. Thread memblokir saat membaca antrian input, mengambil kata pertama dari string, dan meneruskan sisa string ke antrian outputnya. Beberapa fitur dari pendekatan ini:
Yang mengatakan, masih ada banyak daerah abu-abu yang dapat diselidiki oleh pewawancara yang kompeten:
Akhirnya, jika Anda memiliki pengalaman dalam pemrograman bersamaan, Anda mungkin berbicara tentang beberapa kerangka kerja (misalnya, Akka untuk Java / Scala) yang sudah mengikuti model ini.
sumber
Pertanyaan wawancara terkadang adalah pertanyaan tipuan, yang dimaksudkan untuk membuat Anda berpikir tentang masalah yang Anda coba selesaikan. Mengajukan pertanyaan tentang pertanyaan adalah bagian integral dari pendekatan masalah apa pun , apakah itu di dunia nyata atau dalam sebuah wawancara. Ada sejumlah video yang beredar di internet tentang cara mendekati pertanyaan dalam wawancara teknis (lihat khususnya untuk Google dan mungkin Microsoft).
Mendekati wawancara dengan pola pikir ini akan membuat Anda membom wawancara apa pun untuk perusahaan apa pun yang layak bekerja.
Jika Anda tidak berpikir bahwa Anda mendapatkan banyak (jika ada sesuatu dari threading), katakan itu. Katakan kepada mereka mengapa Anda tidak berpikir ada manfaatnya. Berdiskusi dengan mereka. Wawancara teknis dimaksudkan sebagai platform diskusi terbuka. Anda mungkin akhirnya belajar sesuatu tentang bagaimana itu bisa bermanfaat. Jangan hanya terus maju mencoba menerapkan sesuatu yang diwawancarai pewawancara Anda.
sumber
Pertama-tama tokenize paragraf dengan pembatas yang sesuai dan tambahkan kata-kata ke Antrian.
Buat N jumlah utas dan simpan di kumpulan utas.
Iterasi di atas kumpulan utas dan mulai utas dan tunggu
utas bergabung. Dan mulai utas berikutnya setelah utas pertama berakhir dan seterusnya.
Setiap Thread seharusnya hanya mengumpulkan antrian dan mencetaknya.
Setelah semua utas digunakan dalam kumpulan utas, mulailah dari awal pool.
sumber
Seperti yang Anda katakan, saya tidak berpikir skenario ini sangat bermanfaat, jika sama sekali dari threading. Kemungkinan besar lebih lambat dari implementasi threaded tunggal.
Namun, jawaban saya adalah meminta setiap utas dalam satu lingkaran ketat mencoba mengakses kunci yang mengontrol akses ke indeks susunan kata. Setiap utas mengambil kunci, mendapatkan indeks, mendapatkan kata yang sesuai dari array, mencetaknya, menambah indeks lalu melepaskan kunci. Thread keluar saat indeks berada di akhir array.
Sesuatu seperti ini:
Saya pikir ini harus mencapai satu utas setelah persyaratan lain, tetapi pemesanan utas tidak dijamin. Saya penasaran mendengar solusi lain juga.
sumber
Gunakan API tunggu / sinyal kondisi untuk mengatasi masalah ini.
Katakanlah utas pertama mengambil 1 kata dan sementara itu semua utas lainnya sedang menunggu sinyal. 1 utas mencetak kata 1 dan menghasilkan sinyal ke utas berikutnya dan kemudian utas 2 mencetak kata kedua dan menghasilkan sinyal ke utas ke-3 dan seterusnya.
sumber
[Istilah yang digunakan di sini mungkin khusus untuk utas POSIX]
Seharusnya dimungkinkan untuk menggunakan mutasi FIFO juga untuk menyelesaikan masalah ini.
Tempat menggunakan:
Asumsikan dua utas T1 dan T2 sedang mencoba untuk mengeksekusi bagian kritis. Keduanya tidak memiliki banyak pekerjaan di luar bagian penting ini dan menahan kunci untuk waktu yang baik. Jadi, T1 dapat mengunci, menjalankan dan membuka kunci dan memberi sinyal T2 untuk bangun. Tapi sebelum T2 bisa bangun dan mendapatkan kunci, T1 meminta kunci dan mengeksekusi. Dengan cara ini, T2 mungkin harus menunggu sangat lama sebelum benar-benar mendapatkan kunci atau mungkin tidak.
Bagaimana cara kerjanya / Bagaimana menerapkan:
Miliki mutex untuk dikunci. Initialize Thread Specific Data (TSD) untuk setiap utas ke simpul yang berisi utas id dan semaphore. Juga, memiliki dua variabel - dimiliki (BENAR atau SALAH atau -1), pemilik (id utas pemilik). Selain itu, buat antrian pelayan dan penunjuk pelayan. Terakhir menunjuk ke simpul terakhir dalam antrian pelayan.
operasi kunci:
buka kunci operasi:
sumber
Pertanyaan menarik. Ini solusi saya di Java menggunakan SynchronousQueue untuk membuat saluran pertemuan di antara utas:
sumber
Saya akan mengatakan bahwa pertanyaan semacam ini sangat sulit dijawab, karena pertanyaan itu menanyakan cara terbaik untuk melakukan sesuatu yang benar-benar bodoh. Otak saya tidak berfungsi seperti itu. Tidak dapat menemukan solusi untuk pertanyaan bodoh. Otak saya akan segera mengatakan bahwa dalam kondisi ini, menggunakan beberapa utas tidak ada gunanya, jadi saya akan menggunakan satu utas.
Saya kemudian akan meminta mereka untuk memberikan pertanyaan dunia nyata tentang threading, atau untuk memberi saya contoh dunia nyata dari beberapa threading serius.
sumber