Saya akan melalui program yang ditulis dalam C / C ++ untuk kontrol dalam robotika. Pada dasarnya, tiga program berbeda berjalan secara bersamaan, dan mereka berkomunikasi melalui memori bersama. Google-ling sekitar saya menemukan berpikir seperti vxWorks dan meningkatkan header interprocess perpustakaan ( Meningkatkan dokumentasi: Berbagi memori antara proses ).
Sekarang, saya tidak ingin melihat implementasinya, saya bisa membaca tautan di atas. Tapi saya tidak bisa mendapatkan kepala saya sekitar bagaimana perpustakaan meningkatkan melakukan ini. Maksud saya, satu aplikasi mengalokasikan memori, dan lainnya mengakses memori itu, tetapi bagaimana mereka berkomunikasi? bukankah tidak aman untuk melakukan ini?
Jawaban:
Mekanisme antar proses boost memiliki tiga komponen yang diperlukan untuk bekerja:
file yang dipetakan memori: file yang dipetakan memori perlu dibuat dan diteruskan ke pengalokasi proses boost.inter. Pengalokasi ini akan mengambil potongan file dan menggunakannya seolah-olah dikembalikan oleh std :: pengalokasi, dengan pemetaan diterapkan sehingga memori kompatibel dengan memori spesifik yang sedang diproses.
boost.interprocess container; wadah jenis ini akan menggunakan memori yang dikembalikan oleh pengalokasi dan menawarkan antarmuka std :: container like (begin / end / size / push_back, dll).
mekanisme sinkronisasi; ini bisa berupa mutasi antarproses dan harus digunakan untuk mencegah kondisi ras akses data.
Memori yang dialokasikan sebenarnya adalah file yang dipetakan dengan memori bersama. Komunikasi tidak langsung, dengan kedua aplikasi mengatur atau membaca data, sesuai kebutuhan. Keamanan berasal dari penggunaan primitif sinkronisasi antarproses.
sumber
memori bersama bukanlah gambaran lengkap untuk IPC, ini merupakan mekanisme penyampaian data tetapi Anda masih perlu beberapa cara untuk memberi tahu proses lain bahwa beberapa data telah diperbarui dan tersedia untuk dibaca. Bagaimana Anda melakukan ini terserah Anda, biasanya Anda akan menggunakan mutex OS atau objek acara, setiap proses menunggu ini untuk ditetapkan, penulisan aplikasi menetapkannya setelah penulisan selesai. Kemudian utas di program lain bangun dan membaca.
Atau Anda dapat melakukan polling, membaca data secara teratur untuk nilai yang berubah ketika data diperbarui (misalnya penghitung yang bertambah).
sumber
Boost menggunakan pemetaan memori suatu file.
Unix dan windows mendukung pembuatan file yang tidak ada pada sistem file normal hanya untuk tujuan ini.
Maka Anda perlu menyinkronkan akses ke memori itu seperti yang Anda lakukan jika ada utas yang mengaksesnya. Berarti membaca bersamaan dapat terjadi tanpa sinkronisasi tetapi begitu satu proses ingin menulis Anda harus mencegah yang lain mengaksesnya.
Pengoperasian atom pada memori bersama masih dimungkinkan jika Anda ingin sinkronisasi tanpa kunci.
sumber
std::atomic
kelas template C ++ 11 ( cplusplus.com/reference/atomic ) di masing-masing dari dua program agar mereka dapat menulis ke ruang bersama tanpa sinkronisasi yang dipaksakan melalui kunci?Memori bersama masih hanya memori. Anda dapat meletakkan mutex, spinlock, atau primitif sinkronisasi lainnya di sana, dan menggunakannya untuk menyinkronkan akses proses Anda ke memori bersama, persis seperti utas menggunakan primitif itu untuk menyinkronkan akses ke memori yang terlihat oleh mereka.
Satu-satunya perbedaan nyata adalah:
utas berbagi semua memori dan ruang alamat yang sama, jadi pointer mentah berfungsi untuk mereka. Memori yang dibagikan antar proses bekerja persis sama, tetapi dapat dipetakan pada alamat yang berbeda di setiap proses, sehingga Anda tidak bisa dengan mudah melewati petunjuk mentah di antara mereka.
beberapa primitif sinkronisasi mungkin memerlukan flag atau atribut khusus untuk bekerja dengan benar di antara proses (lihat
PTHREAD_PROCESS_SHARED
atribut untuk mutex thread POSIX, misalnya). Ini tidak benar-benar berkaitan dengan memori dan sinkronisasi dalam diri mereka sendiri, tetapi karena interaksi kernel / scheduler diperlukan untuk membangunkan pelayan tidur.Begitu:
Dengan cara yang sama, berbagai utas berkomunikasi, memungkinkan untuk peringatan di atas
Ya, ini sama tidak amannya untuk proses berkomunikasi melalui memori bersama seperti halnya utas untuk berkomunikasi melalui memori bersama, dan mereka membutuhkan sinkronisasi yang setara (atau identik) untuk membuatnya aman.
sumber
Perhatikan bahwa C dan C ++ adalah bahasa yang berbeda.
Memori bersama tidak mungkin dalam C11 murni standar , atau C ++ 11 (karena standar tidak mendefinisikan itu), atau bahkan C ++ 14 (yang n3690 draft, dan mungkin standar resmi, tidak menyebutkan memori bersama di luar multi-threading ). Jadi, Anda perlu perpustakaan tambahan untuk mendapatkan memori bersama. Tetapi beberapa sistem operasi memiliki dukungan untuk memori bersama. Jadi beberapa perpustakaan menyediakan memori bersama, dibangun di atas layanan sistem operasi yang ada, ada. Anda mungkin dapat mempertimbangkan untuk menggunakan perpustakaan kerangka POCO (yang abstrak atas rincian spesifik OS)
Untuk Linux (dan mungkin POSIX), lihat shm_overview (7) . Anda harus menyinkronkan, jadi lihat juga sem_overview (7)
VXWorks (yang saya tidak tahu, tetapi googled untuk itu) memiliki VxMP
Anda harus hati-hati memahami apa yang sebenarnya terjadi. Anda mungkin ingin berbagi hanya data lama
struct
-s (bukan kelas C ++!) Dan Anda harus sangat berhati-hati tentang alamat (setiap proses mungkin mendapatkan alamat yang berbeda untuk segmen memori bersama bersama) dan tentang sinkronisasi.Atau, gunakan utas. Perhatikan bahwa standar C ++ 11 mendefinisikan pustaka thread .
sumber