Memorie partajată

Memoria partajată este cel  mai rapid mijloc de schimb de date între procese [1] .

În alte instrumente de comunicare între procese ( IPC ), comunicarea între procese trece prin nucleu , rezultând o comutare de context între proces și nucleu, de exemplu. la pierderi de performanță [2] .

Tehnica memoriei partajate permite schimbul de informații printr-un segment de memorie partajată pentru procese fără a utiliza apeluri de sistem kernel. Segmentul de memorie partajată este conectat la partea liberă a spațiului de adrese virtuale a procesului [3] . Astfel, două procese diferite pot avea adrese diferite ale aceleiași locații de memorie partajată.

Scurtă descriere a lucrării

După crearea unui segment de memorie partajată, oricare dintre procesele utilizatorului îl poate atașa la propriul spațiu virtual și poate lucra cu el ca și cu un segment de memorie normal. Dezavantajul unui astfel de schimb de informații este absența oricăror mijloace de sincronizare, totuși, pentru a depăși acest dezavantaj, se poate folosi tehnica semaforului .

Implementarea tehnologiei client-server

În schema schimbului de date între două procese ( client și server ) folosind memoria partajată, trebuie să funcționeze un grup de două semafore. Primul semafor este folosit pentru a bloca accesul la memoria partajată, semnalul său de activare este 1, iar semnalul de refuz este 0. Al doilea semafor este folosit pentru a semnala serverului că clientul a început să lucreze, în timp ce accesul la memoria partajată este blocat și clientul citește datele din memorie. Acum, când operația este apelată de către server, activitatea acesteia va fi suspendată până când memoria este eliberată de client.

Scenariul memoriei partajate

  1. Serverul accesează memoria partajată folosind un semafor.
  2. Serverul scrie date în memoria partajată.
  3. După ce scrierea datelor este completă, serverul eliberează accesul la memoria partajată folosind semaforul.
  4. Clientul accesează memoria partajată prin blocarea accesului la această memorie pentru alte procese folosind un semafor.
  5. Clientul citește datele din memoria partajată și apoi eliberează memoria folosind un semafor.

Implementarea software

În software, memoria partajată se numește:

Deoarece ambele procese pot accesa zona de memorie partajată ca memorie normală, este o modalitate foarte rapidă de comunicare (spre deosebire de alte mecanisme IPC, cum ar fi named pipes , socket-uri UNIX sau CORBA ). Pe de altă parte, această metodă este mai puțin flexibilă, de exemplu, procesele de comunicare trebuie să ruleze pe aceeași mașină (dintre metodele IPC enumerate, numai socket-urile de rețea, a nu fi confundate cu socket-urile de domeniu UNIX, pot comunica prin rețea) și trebuie avut grijă pentru a evita problemele atunci când utilizați memoria partajată pe diferite nuclee de procesor și arhitectură hardware fără un cache coerent .

Comunicarea cu memorie partajată este utilizată, de exemplu, pentru a transfera imagini între o aplicație și un server X pe sisteme Unix sau în cadrul obiectului IStream returnat de CoMarshalInterThreadInterfaceInStream în biblioteca COM Windows.

Bibliotecile partajate sunt de obicei încărcate în memorie o singură dată și mapate în mai multe procese și numai paginile care sunt specifice unui singur proces (deoarece unele ID-uri diferă) sunt duplicate, de obicei printr-un mecanism cunoscut sub numele de copiere la scriere , care atunci când încearcă să scrie în memoria partajată, în tăcere la procesul care apelează la scriere, copiază paginile de memorie și apoi scrie datele în acea copie.

Pe sisteme de operare asemănătoare UNIX

POSIX oferă un API standardizat pentru lucrul cu memoria partajată, POSIX Shared Memory . Una dintre caracteristicile cheie ale familiei de sisteme de operare UNIX este mecanismul de copiere a procesului (apel de sistem fork()), care vă permite să creați zone anonime de memorie partajată înainte de a copia procesul și să le moșteniți de procesele descendente. După ce procesul este copiat, memoria partajată va fi disponibilă atât pentru procesul părinte, cât și pentru cel copil. [3] [4]

Există două abordări diferite pentru conectarea și utilizarea memoriei partajate:

Memoria partajată în stil UNIX System V

UNIX System V oferă un set de funcții în limbaj C care vă permit să lucrați cu memoria partajată [7] :

  • shmget — crearea unui segment de memorie partajată legat de un identificator întreg sau a unui segment de memorie partajată anonim (dacă este specificată valoarea IPC_PRIVATE în locul identificatorului) [8] ;
  • shmctl - setarea parametrilor segmentului de memorie [9] ;
  • shmat - conectarea segmentului la spațiul de adrese al procesului [4] ;
  • shmdt - deconectarea segmentului din spațiul de adrese al procesului [10] .

Memoria partajată numită înseamnă că fiecare locație de memorie este asociată cu o cheie numerică unică în sistemul de operare, care poate fi folosită ulterior pentru a conecta memoria partajată într-un alt proces. [opt]

Memoria partajată POSIX

POSIX vă permite să asociați un descriptor de fișier cu un obiect de memorie partajată , care este un mecanism mai unificat decât UNIX System V. Următoarele funcții ale limbajului C pot fi folosite pentru a manipula memoria:

  • shm_open — crearea sau conectarea unui obiect de memorie partajată POSIX prin numele său [6] ;
  • shm_unlink — ștergerea unui obiect de memorie partajată după numele său (în acest caz, segmentul de memorie partajată va exista până când acesta va fi deconectat de la toate procesele) [11] ;
  • ftruncate - setează sau modifică dimensiunea memoriei partajate (sau a fișierului mapat cu memorie) [12] ;
  • mmap — atașează un segment de memorie partajat existent sau creează un segment de memorie partajată la spațiul de adrese de proces [3] .
În sistemele de operare ale familiei Windows

Pe sistemul de operare WindowsCreateFileMapping , funcțiile și MapViewOfFile[13] de la MSDN sunt utilizate pentru a crea memorie partajată .

Suport în limbaje de programare

Unele biblioteci C++ oferă acces pe mai multe platforme la memoria partajată . De exemplu, biblioteca Boost oferă o clasă boost::interprocess::shared_memory_object[14] pentru sistemele de operare compatibile cu POSIX , iar biblioteca Qt oferă o clasă QSharedMemorycare unifică accesul la memoria partajată între sistemele de operare cu unele restricții [15] .

În Java 7 sub sistemul de operare GNU/Linux , memoria partajată poate fi implementată prin maparea unui fișier dintr-un director /dev/shm/(sau /run/shm/, în funcție de distribuție) la memorie [16] folosind o metodă mapde clasă java.nio.MappedByteBuffer[17] .

Suportul pentru memorie partajată a fost implementat în multe alte limbaje de programare . Astfel, PHP oferă un API [18] pentru crearea memoriei partajate, ale cărei funcții sunt similare cu cele ale POSIX .

Vezi și

Note

  1. Kolisnichenko Denis Nikolaevici. Dezvoltarea aplicațiilor Linux . - BHV-Petersburg, 01-01-2012. — 430 p. — ISBN 9785977507479 . Arhivat pe 23 iulie 2016 la Wayback Machine
  2. Hyok-Sung Choi, Hee-Chul Yun. Schimbarea contextului și comparația performanței IPC între uClinux și Linux pe procesorul bazat pe ARM9  //  Samsung Electronics: Raport tehnic. - 2004. Arhivat 6 martie 2016.
  3. ↑ 1 2 3 mmhartă . pubs.opengroup.org. Preluat la 3 ianuarie 2016. Arhivat din original la 6 decembrie 2015.
  4. ↑ 12 shmat . _ pubs.opengroup.org. Consultat la 3 ianuarie 2016. Arhivat din original la 30 decembrie 2015.
  5. Interfețe de sistem Capitolul 2 . pubs.opengroup.org. Consultat la 3 ianuarie 2016. Arhivat din original pe 8 ianuarie 2016.
  6. ↑ 12 shm_open . _ pubs.opengroup.org. Data accesului: 3 ianuarie 2016. Arhivat din original pe 21 noiembrie 2015.
  7. Kay A. Robbins. Programarea sistemelor UNIX: comunicare, concurență și fire de execuție . - Prentice Hall PTR, 2003. - p. 512. Arhivat 22 septembrie 2014 la Wayback Machine
  8. ↑ 12 shmget . _ pubs.opengroup.org. Preluat la 3 ianuarie 2016. Arhivat din original la 5 martie 2016.
  9. shmctl . pubs.opengroup.org. Data accesului: 3 ianuarie 2016. Arhivat din original pe 7 decembrie 2015.
  10. shmdt . pubs.opengroup.org. Consultat la 3 ianuarie 2016. Arhivat din original la 12 decembrie 2015.
  11. shm_unlink . pubs.opengroup.org. Preluat la 3 ianuarie 2016. Arhivat din original la 9 noiembrie 2015.
  12. ftruncate . pubs.opengroup.org. Data accesului: 3 ianuarie 2016. Arhivat din original la 1 februarie 2016.
  13. Crearea memoriei partajate cu nume . Consultat la 26 iunie 2014. Arhivat din original pe 5 iunie 2014.
  14. Partajarea memoriei între procese - 1.60.0 . www.boost.org. Data accesului: 4 ianuarie 2016. Arhivat din original pe 29 decembrie 2015.
  15. Clasa QSharedMemory | Qt Core 5.5 . doc.qt.io. Data accesului: 4 ianuarie 2016. Arhivat din original pe 7 decembrie 2015.
  16. shm_overview(7) - Pagina de manual Linux . man7.org. Data accesului: 4 ianuarie 2016. Arhivat din original pe 4 ianuarie 2016.
  17. MappedByteBuffer (Java Platform SE 7) . docs.oracle.com. Data accesului: 4 ianuarie 2016. Arhivat din original pe 15 ianuarie 2016.
  18. Funcții de memorie partajată în PHP-API . Consultat la 26 iunie 2014. Arhivat din original pe 25 iunie 2014.