Tolong jelaskan dari Linux, perspektif Windows?
Saya pemrograman dalam C #, apakah kedua istilah ini membuat perbedaan. Silakan memposting sebanyak mungkin, dengan contoh dan ....
Terima kasih
Tolong jelaskan dari Linux, perspektif Windows?
Saya pemrograman dalam C #, apakah kedua istilah ini membuat perbedaan. Silakan memposting sebanyak mungkin, dengan contoh dan ....
Terima kasih
Untuk Windows, bagian-bagian penting lebih ringan dari pada mutex.
Mutex dapat dibagi antara proses, tetapi selalu menghasilkan panggilan sistem ke kernel yang memiliki beberapa overhead.
Bagian kritis hanya dapat digunakan dalam satu proses, tetapi memiliki keuntungan bahwa mereka hanya beralih ke mode kernel dalam kasus pertengkaran - Pengambilan yang tidak terkendali, yang seharusnya merupakan kasus umum, sangat cepat. Dalam kasus pertengkaran, mereka memasuki kernel untuk menunggu sinkronisasi primitif (seperti acara atau semaphore).
Saya menulis contoh aplikasi cepat yang membandingkan waktu antara keduanya. Pada sistem saya untuk 1.000.000 akuisisi dan rilis yang tidak dibiarkan, mutex membutuhkan waktu lebih dari satu detik. Bagian kritis membutuhkan ~ 50 ms untuk 1.000.000 akuisisi.
Inilah kode tes, saya menjalankan ini dan mendapatkan hasil yang serupa jika mutex pertama atau kedua, jadi kami tidak melihat efek lainnya.
HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;
// Force code into memory, so we don't see any effects of paging.
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
}
QueryPerformanceCounter(&end);
int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);
// Force code into memory, so we don't see any effects of paging.
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);
}
QueryPerformanceCounter(&end);
int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);
printf("Mutex: %d CritSec: %d\n", totalTime, totalTimeCS);
Dari perspektif teoretis, bagian kritis adalah sepotong kode yang tidak boleh dijalankan oleh banyak utas sekaligus karena kode mengakses sumber daya bersama.
Sebuah mutex adalah sebuah algoritma (dan kadang-kadang nama struktur data) yang digunakan untuk melindungi bagian penting.
Semaphores dan Monitor adalah implementasi umum dari mutex.
Dalam praktiknya ada banyak implementasi mutex yang tersedia di windows. Mereka terutama berbeda sebagai konsekuensi dari implementasi mereka oleh tingkat penguncian mereka, cakupan mereka, biaya mereka, dan kinerja mereka di bawah berbagai tingkat pertikaian. Lihat CLR Inside Out - Menggunakan concurrency untuk skalabilitas untuk bagan biaya implementasi mutex yang berbeda.
Primitif sinkronisasi yang tersedia.
The
lock(object)
pernyataan dilaksanakan menggunakanMonitor
- lihat MSDN untuk referensi.Dalam beberapa tahun terakhir banyak penelitian yang dilakukan pada sinkronisasi non-blocking . Tujuannya adalah untuk mengimplementasikan algoritme dengan cara bebas kunci atau bebas menunggu. Dalam algoritma seperti itu suatu proses membantu proses lain untuk menyelesaikan pekerjaan mereka sehingga proses akhirnya dapat menyelesaikan pekerjaannya. Karena itu suatu proses dapat menyelesaikan pekerjaannya bahkan ketika proses lain, yang mencoba melakukan beberapa pekerjaan, hang. Gunakan kunci, mereka tidak akan melepaskan kunci mereka dan mencegah proses lainnya dari melanjutkan.
sumber
Selain jawaban lain, detail berikut khusus untuk bagian penting di windows:
InterlockedCompareExchange
operasiDi linux, saya pikir mereka memiliki "kunci putaran" yang melayani tujuan yang mirip dengan bagian kritis dengan jumlah putaran.
sumber
Critical Section dan Mutex tidak spesifik sistem operasi, konsep multithreading / multiprocessing.
Bagian Kritis Adalah sepotong kode yang hanya boleh dijalankan sendiri pada waktu tertentu (misalnya, ada 5 utas yang berjalan secara bersamaan dan fungsi yang disebut "critical_section_function" yang memperbarui array ... Anda tidak ingin semua 5 utas memperbarui array sekaligus. Jadi ketika program ini menjalankan critical_section_function (), tidak ada thread lain yang harus menjalankan critical_section_function mereka.
mutex * Mutex adalah cara mengimplementasikan kode bagian kritis (anggap saja seperti token ... utas harus memiliki itu untuk menjalankan critical_section_code)
sumber
Mutex adalah objek yang dapat diperoleh thread, mencegah utas lainnya mendapatkannya. Itu adalah nasihat, bukan wajib; sebuah thread dapat menggunakan sumber daya yang diwakili oleh mutex tanpa mendapatkannya.
Bagian kritis adalah panjang kode yang dijamin oleh sistem operasi untuk tidak diinterupsi. Dalam pseudo-code, itu akan seperti:
sumber
Windows 'fast' yang setara dengan pemilihan kritis di Linux akan menjadi futex , yang merupakan singkatan dari mutex ruang pengguna yang cepat. Perbedaan antara futex dan mutex adalah bahwa dengan futex, kernel hanya menjadi terlibat ketika arbitrasi diperlukan, sehingga Anda menghemat biaya bicara dengan kernel setiap kali penghitung atom diubah. Itu .. dapat menyimpan signifikan jumlah waktu kunci negosiasi dalam beberapa aplikasi.
Futex juga dapat dibagikan di antara proses, menggunakan cara yang Anda gunakan untuk berbagi mutex.
Sayangnya, futex bisa sangat sulit untuk diterapkan (PDF). (Pemutakhiran 2018, mereka hampir tidak menakutkan seperti pada 2009).
Selain itu, hampir sama di kedua platform. Anda membuat pembaruan atomik yang didorong token ke struktur bersama dengan cara yang (mudah-mudahan) tidak menyebabkan kelaparan. Yang tersisa hanyalah metode untuk mencapai itu.
sumber
Di Windows, bagian penting adalah lokal untuk proses Anda. Mutex dapat dibagikan / diakses di seluruh proses. Pada dasarnya, bagian kritis jauh lebih murah. Tidak dapat mengomentari Linux secara khusus, tetapi pada beberapa sistem mereka hanya alias untuk hal yang sama.
sumber
Hanya untuk menambahkan 2 sen saya, Bagian kritis didefinisikan sebagai struktur dan operasi pada mereka dilakukan dalam konteks mode pengguna.
Sedangkan mutex adalah objek kernel (ExMutantObjectType) yang dibuat di direktori objek Windows. Operasi mutex sebagian besar diimplementasikan dalam mode kernel. Misalnya, saat membuat Mutex, Anda akhirnya memanggil nt! NtCreateMutant di kernel.
sumber
Jawaban yang bagus dari Michael. Saya telah menambahkan tes ketiga untuk kelas mutex yang diperkenalkan di C ++ 11. Hasilnya agak menarik, dan masih mendukung dukungan aslinya objek CRITICAL_SECTION untuk proses tunggal.
Hasil saya adalah 217, 473, dan 19 (perhatikan bahwa rasio waktu saya untuk dua terakhir kira-kira sebanding dengan Michael, tetapi mesin saya setidaknya empat tahun lebih muda darinya, sehingga Anda dapat melihat bukti peningkatan kecepatan antara 2009 dan 2013 , ketika XPS-8700 keluar). Kelas mutex baru dua kali lebih cepat dari mutex Windows, tetapi masih kurang dari sepersepuluh kecepatan objek Windows CRITICAL_SECTION. Perhatikan bahwa saya hanya menguji mutex non-rekursif. Objek CRITICAL_SECTION bersifat rekursif (satu utas dapat memasukkannya berulang kali, asalkan meninggalkan jumlah yang sama kali).
sumber
Fungsi AC disebut reentrant jika hanya menggunakan parameter aktualnya.
Fungsi reentrant dapat dipanggil oleh banyak utas secara bersamaan.
Contoh fungsi reentrant:
Contoh fungsi non reentrant:
Strtok library C standar () tidak reentrant dan tidak dapat digunakan oleh 2 utas atau lebih pada saat yang sama.
Beberapa platform SDK dilengkapi dengan versi reentrant dari strtok () yang disebut strtok_r ();
Enrico Migliore
sumber