Sdílená paměť

Sdílená paměť je nejrychlejším  prostředkem výměny dat mezi procesy [1] .

V jiných nástrojích inter-process communication ( IPC ) probíhá komunikace mezi procesy přes jádro , což má za následek přepnutí kontextu mezi procesem a jádrem, tzn. ke ztrátám výkonu [2] .

Technika sdílené paměti umožňuje výměnu informací prostřednictvím segmentu sdílené paměti pro procesy bez použití systémových volání jádra. Segment sdílené paměti je připojen k volné části virtuálního adresního prostoru procesu [3] . Dva různé procesy tak mohou mít různé adresy stejného umístění sdílené paměti.

Stručný popis práce

Po vytvoření segmentu sdílené paměti jej může kterýkoli z uživatelských procesů připojit ke svému vlastnímu virtuálnímu prostoru a pracovat s ním jako s běžným segmentem paměti. Nevýhodou takové výměny informací je absence jakýchkoli prostředků synchronizace, k překonání této nevýhody lze však použít semaforovou techniku ​​.

Implementace technologie klient-server

Ve schématu výměny dat mezi dvěma procesy ( klient a server ) pomocí sdílené paměti musí fungovat skupina dvou semaforů. První semafor se používá k blokování přístupu ke sdílené paměti, jeho signál povolení je 1 a signál odmítnutí je 0. Druhý semafor se používá k signalizaci serveru, že klient zahájil práci, zatímco přístup ke sdílené paměti je blokován a klient čte data z paměti. Nyní, když je operace volána serverem, její práce bude pozastavena, dokud klient neuvolní paměť.

Scénář sdílené paměti

  1. Server přistupuje ke sdílené paměti pomocí semaforu.
  2. Server zapisuje data do sdílené paměti.
  3. Po dokončení zápisu dat server uvolní přístup ke sdílené paměti pomocí semaforu.
  4. Klient přistupuje ke sdílené paměti uzamčením přístupu k této paměti pro jiné procesy pomocí semaforu.
  5. Klient čte data ze sdílené paměti a poté paměť uvolňuje pomocí semaforu.

Implementace softwaru

V softwaru se sdílená paměť nazývá:

Protože oba procesy mohou přistupovat k oblasti sdílené paměti jako k normální paměti, je to velmi rychlý způsob komunikace (na rozdíl od jiných mechanismů IPC, jako jsou pojmenované kanály , UNIX sockety nebo CORBA ). Na druhou stranu je tato metoda méně flexibilní, například komunikující procesy musí běžet na stejném stroji (z uvedených metod IPC mohou po síti komunikovat pouze síťové sokety, nezaměňovat se sokety UNIX domény) a je třeba dbát na to, aby se předešlo problémům při používání sdílené paměti na různých jádrech procesoru a hardwarové architektuře bez koherentní mezipaměti .

Komunikace ve sdílené paměti se používá například k přenosu obrázků mezi aplikací a X serverem na systémech Unix nebo v rámci objektu IStream vráceného CoMarshalInterThreadInterfaceInStream v knihovně Windows COM.

Sdílené knihovny jsou obvykle načteny do paměti jednou a mapovány napříč více procesy a duplikovány jsou pouze stránky, které jsou specifické pro jeden proces (protože některá ID se liší), obvykle mechanismem známým jako copy-on-write , který při pokusu o zápis do sdílené paměti, tiše do procesu volajícího zápis, zkopíruje stránky paměti a poté zapíše data do této kopie.

V operačních systémech podobných UNIX

POSIX poskytuje standardizované API pro práci se sdílenou pamětí, POSIX Shared Memory . Jednou z klíčových vlastností operačních systémů rodiny UNIX je mechanismus kopírování procesů (systémové volání fork()), který umožňuje vytvořit anonymní oblasti sdílené paměti před zkopírováním procesu a zdědit je potomky. Po zkopírování procesu bude sdílená paměť dostupná pro nadřazený i podřízený proces. [3] [4]

Existují dva různé přístupy k připojení a používání sdílené paměti:

Sdílená paměť ve stylu UNIX System V

UNIX System V poskytuje sadu funkcí jazyka C, které vám umožňují pracovat se sdílenou pamětí [7] :

  • shmget — vytvoření segmentu sdílené paměti vázaného na celočíselný identifikátor nebo anonymního segmentu sdílené paměti (pokud je místo identifikátoru uvedena hodnota IPC_PRIVATE) ​​[8] ;
  • shmctl - nastavení parametrů paměťového segmentu [9] ;
  • shmat - připojení segmentu k adresnímu prostoru procesu [4] ;
  • shmdt - odpojení segmentu od adresního prostoru procesu [10] .

Pojmenovaná sdílená paměť znamená, že každé paměťové místo je v rámci operačního systému spojeno s jedinečným číselným klíčem, který lze později použít k připojení sdílené paměti v jiném procesu. [osm]

POSIX sdílená paměť

POSIX vám umožňuje přidružit deskriptor souboru k objektu sdílené paměti , což je jednotnější mechanismus než UNIX System V. K manipulaci s pamětí lze použít následující funkce jazyka C:

  • shm_open — vytvoření nebo připojení objektu sdílené paměti POSIX jeho jménem [6] ;
  • shm_unlink — smazání objektu sdílené paměti podle jeho názvu (v tomto případě bude segment sdílené paměti existovat, dokud nebude odpojen od všech procesů) [11] ;
  • ftruncate - nastavuje nebo mění velikost sdílené paměti (nebo paměťově mapovaného souboru) [12] ;
  • mmap — připojí existující nebo vytvoří anonymní segment sdílené paměti k adresnímu prostoru procesu [3] .
V operačních systémech rodiny Windows

V operačním systému Windows se k vytvoření sdílené paměti používají funkce CreateFileMappinga MapViewOfFile[13] z MSDN .

Podpora v programovacích jazycích

Některé knihovny C++ nabízejí přístup ke sdílené paměti napříč platformami . Například knihovna Boost poskytuje třídu boost::interprocess::shared_memory_object[14] pro operační systémy kompatibilní s POSIX a knihovna Qt poskytuje třídu QSharedMemory, která sjednocuje přístup ke sdílené paměti napříč operačními systémy s určitými omezeními [15] .

V Javě 7 pod operačním systémem GNU/Linux lze sdílenou paměť implementovat mapováním souboru z adresáře /dev/shm/(nebo /run/shm/, v závislosti na distribuci) do paměti [16] pomocí metody maptřídy java.nio.MappedByteBuffer[17] .

Podpora sdílené paměti byla implementována v mnoha dalších programovacích jazycích . PHP tedy poskytuje API [18] pro vytváření sdílené paměti, jehož funkce jsou podobné funkcím POSIX .

Viz také

Poznámky

  1. Kolisničenko Denis Nikolajevič. Vývoj linuxových aplikací . - BHV-Petersburg, 01.01.2012. — 430 s. — ISBN 9785977507479 . Archivováno 23. července 2016 na Wayback Machine
  2. Hyok-Sung Choi, Hee-Chul Yun. Přepínání kontextu a srovnání výkonu IPC mezi uClinuxem a Linuxem na procesoru založeném na ARM9  //  Samsung Electronics: Technická zpráva. - 2004. Archivováno 6. března 2016.
  3. ↑ 1 2 3 mmmap . pubs.opengroup.org. Získáno 3. ledna 2016. Archivováno z originálu 6. prosince 2015.
  4. ↑ 12 shmatů . _ pubs.opengroup.org. Získáno 3. ledna 2016. Archivováno z originálu 30. prosince 2015.
  5. Systémová rozhraní Kapitola 2 . pubs.opengroup.org. Získáno 3. ledna 2016. Archivováno z originálu 8. ledna 2016.
  6. ↑ 12 shm_open . _ pubs.opengroup.org. Datum přístupu: 3. ledna 2016. Archivováno z originálu 21. listopadu 2015.
  7. Kay A. Robbins. Programování systémů UNIX: komunikace, souběžnost a vlákna . - Prentice Hall PTR, 2003. - s. 512. Archivováno 22. září 2014 na Wayback Machine
  8. ↑ 12 shmget . _ pubs.opengroup.org. Získáno 3. ledna 2016. Archivováno z originálu 5. března 2016.
  9. shmctl . pubs.opengroup.org. Datum přístupu: 3. ledna 2016. Archivováno z originálu 7. prosince 2015.
  10. shmdt . pubs.opengroup.org. Získáno 3. ledna 2016. Archivováno z originálu 12. prosince 2015.
  11. shm_unlink . pubs.opengroup.org. Získáno 3. ledna 2016. Archivováno z originálu 9. listopadu 2015.
  12. fruncate . pubs.opengroup.org. Datum přístupu: 3. ledna 2016. Archivováno z originálu 1. února 2016.
  13. Vytvoření pojmenované sdílené paměti . Získáno 26. června 2014. Archivováno z originálu 5. června 2014.
  14. Sdílení paměti mezi procesy - 1.60.0 . www.boost.org. Datum přístupu: 4. ledna 2016. Archivováno z originálu 29. prosince 2015.
  15. Třída QSharedMemory | Qt Core 5.5 . doc.qt.io. Datum přístupu: 4. ledna 2016. Archivováno z originálu 7. prosince 2015.
  16. shm_overview(7) – manuálová stránka Linuxu . man7.org. Datum přístupu: 4. ledna 2016. Archivováno z originálu 4. ledna 2016.
  17. MappedByteBuffer (Java Platform SE 7) . docs.oracle.com. Datum přístupu: 4. ledna 2016. Archivováno z originálu 15. ledna 2016.
  18. Funkce sdílené paměti v PHP-API . Získáno 26. června 2014. Archivováno z originálu 25. června 2014.