Semenalidery.com

IT Новости из мира ПК
2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Linux shared memory

ЋЎй п (б®ў¬Ґбв­® ЁбЇ®«м§гҐ¬ п) Ї ¬пвм

Ћ¤Ё­ Ё§ б ¬ле Їа®бвле ¬Ґв®¤®ў ¬Ґ¦Їа®жҐбб®ў®Ј® ў§ Ё¬®¤Ґ©бвўЁп — ЁбЇ®«м§®ў вм ®Ўйго Ї ¬пвм. ЋЎй п Ї ¬пвм Ї®§ў®«пҐв ¤ўг¬ Ё«Ё Ў®«ҐҐ Їа®жҐбб ¬ ®Ўа й вмбп Є ®¤­®© Ё в®© ¦Ґ ®Ў« бвЁ Ї ¬пвЁ, Є Є Ўг¤в® ®­Ё ўбҐ ўл§лў «Ё malloc Ё Ё¬ Ўл«Ё ў®§ўа 饭л гЄ § ⥫Ё ­ ®¤­г Ё вг ¦Ґ дЁ§ЁзҐбЄго Ї ¬пвм. Љ®Ј¤ ®¤Ё­ Їа®жҐбб Ё§¬Ґ­пҐв Ї ¬пвм, ўбҐ ¤агЈЁҐ Їа®жҐббл «ўЁ¤пв» ¬®¤ЁдЁЄ жЁо.

Ѓлбв஥ «®Є «м­®Ґ ў§ Ё¬®¤Ґ©бвўЁҐ

ЋЎй п Ї ¬пвм — б ¬ п Ўлбва п д®а¬ ¬Ґ¦Їа®жҐбб®ў®Ј® ў§ Ё¬®¤Ґ©бвўЁп, Ї®в®¬г зв® ўбҐ Їа®жҐббл б®ў¬Ґбв­® ЁбЇ®«м§гов ®¤­г Ёвг ¦Ґ з бвм Ї ¬пвЁ. „®бвгЇ Є нв®© ®ЎйҐ© Ї ¬пвЁ ®бгйҐбвў«пҐвбп б в®© ¦Ґ бЄ®а®бвмо, зв® Ё ЇаЁ ®Ўа 饭ЁЁ Є ­Ґб®ў¬Ґбв­® ЁбЇ®«м§гҐ¬®© Ї ¬пвЁ, Ё нв® ­Ґ вॡгҐв бЁб⥬­®Ј® ўл§®ў Ё«Ё ўе®¤ ў п¤а®. ќв® в Є¦Ґ ­Ґ вॡгҐв Ё§«Ёи­ҐЈ® Є®ЇЁа®ў ­Ёп ¤ ­­ле.

Џ®бЄ®«мЄг п¤а® ­Ґ бЁ­еа®­Ё§ЁагҐв ¤®бвгЇл Є б®ў¬Ґбв­® ЁбЇ®«м§гҐ¬®© Ї ¬пвЁ, ўл ¤®«¦­л б ¬Ё ®ЎҐбЇҐзЁвм бЁ­еа®­Ё§ жЁо. Ќ ЇаЁ¬Ґа, Їа®жҐбб ­Ґ ¤®«¦Ґ­ зЁв вм Ё§ Ї ¬пвЁ, Ї®Є ¤ ­­лҐ ­Ґ § ЇЁб ­л вг¤ , Ё ¤ў Їа®жҐбб ­Ґ ¤®«¦­л ­ ЇЁб вм Ї® ®¤­®¬г Ё ⮬㠦Ґ ¤аҐбг Ї ¬пвЁ ў ®¤­® Ё в® ¦Ґ ўаҐ¬п. ЋЎй п бва ⥣Ёп Ё§ЎҐ¦ ­Ёп гб«®ўЁ© Ј®­ЄЁ б®бв®Ёв ў ⮬, зв®Ўл ЁбЇ®«м§®ў вм ᥬ д®ал.

Њ®¤Ґ«м Ї ¬пвЁ

—в®Ўл ЁбЇ®«м§®ў вм ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ, ®¤Ё­ Їа®жҐбб ¤®«¦Ґ­ ўл¤Ґ«Ёвм ᥣ¬Ґ­в. ’®Ј¤ Є ¦¤л© Їа®жҐбб, ¦Ґ« ойЁ© ®Ўа й вмбп Є ᥣ¬Ґ­вг ¤®«¦Ґ­ Ї®¤Є«озЁвм ᥣ¬Ґ­в. Џ®б«Ґ ®Є®­з ­Ёп ҐЈ® ЁбЇ®«м§®ў ­Ёп ᥣ¬Ґ­в , Є ¦¤л© Їа®жҐбб ®вЄ«оз Ґв ᥣ¬Ґ­в. ‚ ­ҐЄ®в®ал© ¬®¬Ґ­в, ®¤Ё­ Їа®жҐбб ¤®«¦Ґ­ ®бў®Ў®¤Ёвм ᥣ¬Ґ­в.

Џ®­Ё¬ ­ЁҐ ¬®¤Ґ«Ё Ї ¬пвЁ Linux Ї®¬®Ј Ґв ®Ўкпб­Ёвм Їа®жҐбб ўл¤Ґ«Ґ­Ёп Ё Ї®¤Є«о祭Ёп. Џ®¤ Linux , ўЁавг «м­ п Ї ¬пвм Є ¦¤®Ј® Їа®жҐбб а §ЎЁв ­ бва ­Ёжл. Љ ¦¤л© Їа®жҐбб Ї®¤¤Ґа¦Ёў Ґв ®в®Ўа ¦Ґ­ЁҐ ҐЈ® ¤аҐб®ў Ї ¬пвЁ ­ нвЁ бва ­Ёжл ўЁавг «м­®© Ї ¬пвЁ, Є®в®алҐ б®¤Ґа¦ в д ЄвЁзҐбЄЁҐ ¤ ­­лҐ. € е®вп Є ¦¤л© Їа®жҐбб Ё¬ҐҐв б®Ўб⢥­­лҐ ¤аҐб , ®в®Ўа ¦Ґ­Ёп ¬­®ЈЁе Їа®жҐбб®ў ¬®Јгв гЄ §лў вм ­ ®¤­г Ё вг ¦Ґ бва ­Ёжг, а §аҐи п б®ў¬Ґбв­®Ґ ЁбЇ®«м§®ў ­ЁҐ Ї ¬пвЁ.

‚뤥«Ґ­ЁҐ ­®ў®Ј® ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ ЇаЁў®¤Ёв Є ᮧ¤ ­Ёо бва ­Ёжл ўЁавг «м­®© Ї ¬пвЁ. Џ®бЄ®«мЄг ўбҐ Їа®жҐббл ¦Ґ« ов ®Ўа вЁвмбп Є ®¤­®¬г Ё ⮬㠦Ґ ®ЎйҐ¬г ᥣ¬Ґ­вг, в® в®«мЄ® ®¤Ё­ Їа®жҐбб ¤®«¦Ґ­ ўл¤Ґ«Ёвм ­®ўл© ®ЎйЁ© ᥣ¬Ґ­в. ‚뤥«Ґ­ЁҐ бгйҐбвўго饣® ᥣ¬Ґ­в ­Ґ ᮧ¤ Ґв ­®ўле бва ­Ёж, ў®§ўа й Ґв Ё¤Ґ­вЁдЁЄ в®а ¤«п бгйҐбвўгойЁе. —в®Ўл а §аҐиЁвм Їа®жҐббг ЁбЇ®«м§®ў вм ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ, Їа®жҐбб Ї®¤Є«оз Ґв ᥣ¬Ґ­в, Є®в®ал© ¤®Ў ў«пҐв ®в®Ўа ¦Ґ­ЁҐ ҐЈ® ўЁавг «м­®© Ї ¬пвЁ ­ ®ЎйҐ¤®бвгЇ­лҐ бва ­Ёжл ᥣ¬Ґ­в . Љ®Ј¤ а Ў®в б ᥣ¬Ґ­в®¬ § ўҐа襭 , нвЁ ®в®Ўа ¦Ґ­Ёп г¤ «повбп. Љ®Ј¤ ­Ё ®¤­Ё Ё§ Їа®жҐбб®ў ­Ґ е®зҐв ®Ўа й вмбп Є ᥣ¬Ґ­в ¬ ®ЎйҐ© Ї ¬пвЁ, Є Є®©-в® ®¤Ё­ Їа®жҐбб ¤®«¦Ґ­ ®бў®Ў®¤Ёвм бва ­Ёжл ўЁавг «м­®© Ї ¬пвЁ. ‚ᥠᥣ¬Ґ­вл ®ЎйҐ© Ї ¬пвЁ ўл¤Ґ«повбп Ї®бва ­Ёз­® Ё ®ЄагЈ«повбп ¤® а §¬Ґа бва ­Ёжл бЁб⥬л, Є®в®ал© пў«пҐвбп зЁб«®¬ Ў ©в®ў ў бва ­ЁжҐ Ї ¬пвЁ. Ќ бЁб⥬ е Linux , а §¬Ґа бва ­Ёжл а ўҐ­ 4 ЉЃ, ­® ўл ¤®«¦­л Ї®«гзЁвм нв® §­ 祭ЁҐ, ўл§лў п дг­ЄжЁо getpagesize .

‚뤥«Ґ­ЁҐ

Џа®жҐбб ўл¤Ґ«пҐв ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ, ЁбЇ®«м§гп shmget (» SHared Memory GET «). …Ј® ЇҐаўл© Ї а ¬Ґва — 楫®зЁб«Ґ­­л© Є«оз, Є®в®ал© ®ЇаҐ¤Ґ«пҐв, Є Є®© ᥣ¬Ґ­в ᮧ¤ вм. ЌҐбўп§ ­­лҐ Їа®жҐббл ¬®Јгв ®Ўа й вмбп Є ®¤­®¬г Ё ⮬㠦Ґ ᥣ¬Ґ­вг, ЁбЇ®«м§гп ®¤­® Ё в® ¦Ґ Є«о祢®Ґ §­ 祭ЁҐ. Љ ᮦ «Ґ­Ёо, ¤агЈЁҐ Їа®жҐббл, ў®§¬®¦­®, в Є¦Ґ ўлЎа «Ё в®в ¦Ґ б ¬л© Є«оз, зв® ¬®¦Ґв ЇаЁўҐбвЁ Є Є®­д«ЁЄвг. €бЇ®«м§гп бЇҐжЁ «м­го Є®­бв ­вг IPC_PRIVATE Є Є Є«о祢®Ґ §­ 祭ЁҐ, Ј а ­вЁагҐвбп, з⮠ᮧ¤ бвбп б®ўҐа襭­® ­®ўл© ᥣ¬Ґ­в Ї ¬пвЁ.

…Ј® ўв®а®© Ї а ¬Ґва ®ЇаҐ¤Ґ«пҐв зЁб«® Ў ©в®ў ў ᥣ¬Ґ­вҐ. Џ®бЄ®«мЄг ᥣ¬Ґ­вл ўл¤Ґ«повбп Ї®бва ­Ёз­®, зЁб«® д ЄвЁзҐбЄЁ ўл¤Ґ«Ґ­­ле Ў ©в ®ЄагЈ«пҐвбп ¤® а §¬Ґа бва ­Ёжл.

’аҐвЁ© Ї а ¬Ґва — Ї®а §ап¤­®Ґ ¤ў®Ёз­®Ґ Ё«Ё §­ 祭Ё© д« ¦Є , Є®в®алҐ ®ЇаҐ¤Ґ«пов ®ЇжЁЁ Є shmget . ‡­ 祭Ёп д« ¦Є ўЄ«оз ов в ЄЁҐ Ї а ¬Ґвал:

  • IPC_CREAT — нв®в д« ¦®Є гЄ §лў Ґв, зв® ¤®«¦Ґ­ Ўлвм ᮧ¤ ­ ­®ўл© ᥣ¬Ґ­в. ќв® а §аҐи Ґв ᮧ¤ ў вм ­®ўл© ᥣ¬Ґ­в, ®ЇаҐ¤Ґ«пп Є«оз.
  • IPC_EXCL — нв®в д« ¦®Є, Є®в®ал© ўбҐЈ¤ ЁбЇ®«м§гҐвбп б IPC_CREAT ,§ бв ў«пҐв shmget ў®§ўа й вм ®иЁЎЄг, Ґб«Ё ᥣ¬Ґ­в­л© Є«оз ®ЇаҐ¤Ґ«Ґ­, Є Є 㦥 бгйҐбвўгойЁ©. ќв® ЁбЇ®«м§гҐвбп ¤«п ўл¤Ґ«Ґ­Ёп «нЄбЄ«о§Ёў­®Ј®» ᥣ¬Ґ­в . …б«Ё нв®в д« ¦®Є ­Ґ ¤ Ґвбп, Ё Є«оз бгйҐбвўго饣® ᥣ¬Ґ­в ЁбЇ®«м§гҐвбп, shmget ў®§ўа й Ґв бгйҐбвўгойЁ© ᥣ¬Ґ­в ў¬Ґбв® в®Ј®, зв®Ўл ᮧ¤ вм ­®ўл©.
  • Mode flags — нв® §­ 祭ЁҐ Ё§ 9 ЎЁв®ў, гЄ §лў ойЁе Їа ў , ЇаҐ¤®бв ў«Ґ­­лҐ ў« ¤Ґ«мжг, ЈагЇЇҐ, Ё ¬Ёаг(®бв «м­л¬), ­ гЇа ў«Ґ­ЁҐ ¤®бвгЇ®¬ Є ᥣ¬Ґ­вг. ЃЁвл ўлЇ®«­Ґ­Ёп ЁЈ­®аЁаговбп. Џа®бв®© бЇ®б®Ў ®ЇаҐ¤Ґ«Ёвм Їа ў б®бв®Ёв ў ⮬, зв®Ўл ЁбЇ®«м§®ў вм Є®­бв ­вл, ®ЇаҐ¤Ґ«Ґ­­лҐ ў Ё ®ЇЁб ­лҐ ў а §¤Ґ«Ґ 2 stat man-бва ­Ёж . Ќ ЇаЁ¬Ґа, S_IRUSR Ё S_IWUSR ®ЇаҐ¤Ґ«пов Їа ў ­ з⥭ЁҐ Ё § ЇЁбм ¤«п ў« ¤Ґ«мж ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ, S_IROTH Ё S_IWOTH ®ЇаҐ¤Ґ«пов Їа ў ­ з⥭ЁҐ Ё § ЇЁбм ¤«п ¤агЈЁе.

Ќ ЇаЁ¬Ґа, нв®в ўл§®ў shmget ᮧ¤ Ґв ­®ўл© ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ (Ё«Ё ®Ўа й Ґвбп Є бгйҐбвўго饬г, Ґб«Ё shm_key 㦥 ЁбЇ®«м§гҐвбп), б Їа ў ¬Ё ­ зЁвҐ­ЁҐ Ё § ЇЁбм ў« ¤Ґ«м楬, ­® ­Ґ ¤агЈЁ¬Ё Ї®«м§®ў ⥫ﬨ.

…б«Ё ўл§®ў гᯥ襭, shmget ў®§ўа й Ґв Ё¤Ґ­вЁдЁЄ в®а ᥣ¬Ґ­в . …б«Ё ᥣ¬Ґ­в ®ЎйҐ© Ї ¬п⨠㦥 бгйҐбвўгҐв, в® Їа ў ­ ¤®бвгЇ Їа®ўҐаҐ­л, Ё Їа®ўҐаЄ Ј а ­вЁагҐв, з⮠ᥣ¬Ґ­в ­Ґ ®в¬ҐзҐ­ ¤«п г¤ «Ґ­Ёп.

Џ®¤Є«о祭ЁҐ Ё ®вЄ«о祭ЁҐ

—в®Ўл ᤥ« вм ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ ¤®бвгЇ­л¬, Їа®жҐбб ¤®«¦Ґ­ ЁбЇ®«м§®ў вм shmat , » SHared Memory ATtach » ЏҐаҐ¤ ©вҐ Ґ¬г Ё¤Ґ­вЁдЁЄ в®а ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ SHMID , ў®§ўа 饭­л© shmget . ‚в®а®© Ї а ¬Ґва — гЄ § ⥫м, Є®в®ал© ®ЇаҐ¤Ґ«пҐв, Ј¤Ґ ў ¤аҐб­®¬ Їа®бва ­б⢥ ў 襣® Їа®жҐбб ўл е®вЁвҐ ®в®Ўа §Ёвм ®Ўйго Ї ¬пвм; Ґб«Ё ўл ЇҐаҐ¤ ¤ЁвҐ NULL , в® Linux ўлЎҐаҐв «оЎ®© ¤®бвгЇ­л© ¤аҐб. ’аҐвЁ© Ї а ¬Ґва — д« ¦®Є, Є®в®ал© ¬®¦Ґв ўЄ«озЁвм б«Ґ¤гойЁҐ Ї а ¬Ґвал:

  • SHM_RND гЄ §лў Ґв, зв® ¤аҐб, ®ЇаҐ¤Ґ«Ґ­­л© ¤«п ўв®а®Ј® Ї а ¬Ґва , ¤®«¦Ґ­ Ўлвм ®ЄагЈ«Ґ­ ­ § ¤ Є ¬­®¦ЁвҐ«о а §¬Ґа бва ­Ёжл. …б«Ё ‚л ­Ґ ®ЇаҐ¤Ґ«пҐвҐ нв®в д« ¦®Є, ‚л ¤®«¦­л ўла®ў­пвм ­ Ја ­Ёжг бва ­Ёжл ўв®а®© Ї а ¬Ґва ЇҐаҐ¤ ў Ґ¬л© shmat б ¬®бв®п⥫쭮.
  • SHM_RDONLY гЄ §лў Ґв, з⮠ᥣ¬Ґ­в Ўг¤Ґв ¤®бвгЇҐ­ в®«мЄ® ¤«п з⥭Ёп.
  • ЃЁвл Їа ў ¤®бв Ї в ЄЁҐ ¦Ґ Є Є Ё ¤«п д ©«®ў.

…б«Ё ўл§®ў гᯥ襭, ®­ ўҐа­Ґв ¤аҐб Ї®¤Є«о祭­®Ј® ®ЎйҐЈ® ᥣ¬Ґ­в . Џ®в®¬ЄЁ, ᮧ¤ ­­лҐ ўл§®ў ¬Ё fork , ­ б«Ґ¤гов Ї®¤Є«о祭­лҐ ®ЎйЁҐ ᥣ¬Ґ­вл; ®­Ё ¬®Јгв ®вЄ«озЁвм ᥣ¬Ґ­вл ®ЎйҐ© Ї ¬пвЁ, Ґб«Ё § е®впв.

Љ®Ј¤ ўл § Є®­зЁ«Ё а Ў®вг б ᥣ¬Ґ­в®¬ ®ЎйҐ© Ї ¬пвЁ, ᥣ¬Ґ­в ¤®«¦Ґ­ Ўлвм ®вЄ«о祭, ЁбЇ®«м§гп shmdt (» SHared Memory DeTach «). ЏҐаҐ¤ ©вҐ Ґ¬г ¤аҐб, ў®§ўа 饭­л© shmat . …б«Ё ᥣ¬Ґ­в Ўл« ®бў®Ў®¦¤Ґ­, Ё Ў®«миҐ ­Ґ ®бв «®бм Їа®жҐбб®ў, ЁбЇ®«м§гойЁе ҐЈ®, ®­ Ўг¤Ґв г¤ «Ґ­. ‚맮ўл exit Ё exec ўв®¬ вЁзҐбЄЁ ®вЄ«оз ов ᥣ¬Ґ­вл.

“Їа ў«Ґ­ЁҐ Ё ®бў®Ў®¦¤Ґ­ЁҐ ®ЎйҐ© Ї ¬пвЁ

Shmctl (» SHared Memory ConTrol «) ўл§®ў ў®§ўа й Ґв Ё­д®а¬ жЁо ®Ў ᥣ¬Ґ­вҐ ®ЎйҐ© Ї ¬пвЁ Ё ¬®¦Ґв Ё§¬Ґ­Ёвм ҐЈ®.ЏҐаўл© Ї а ¬Ґва — Ё¤Ґ­вЁдЁЄ в®а ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ.

—в®Ўл Ї®«гзЁвм Ё­д®а¬ жЁо ® ᥣ¬Ґ­вҐ ®ЎйҐ© Ї ¬пвЁ, ЇҐаҐ¤ ©вҐ IPC_STAT Є Є ўв®а®© Ї а ¬Ґва Ё гЄ § вҐ«м ­ struct shmid_ds .

—в®Ўл г¤ «Ёвм ᥣ¬Ґ­в, ЇҐаҐ¤ ©вҐ IPC_RMID Є Є ўв®а®© Ї а ¬Ґва, Ё ЇҐаҐ¤ ©вҐ NULL Є Є ваҐвЁ© Ї а ¬Ґва. ‘ҐЈ¬Ґ­в г¤ «Ґ­, Є®Ј¤ Ї®б«Ґ¤­Ё© Їа®жҐбб, Є®в®ал© Ї®¤Є«озЁ« ҐЈ®, ®вЄ«озЁв ҐЈ®.

Љ ¦¤л© ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ ¤®«¦Ґ­ Ўлвм пў­® ®бў®Ў®¦¤Ґ­, ЁбЇ®«м§гп shmctl , Є®Ј¤ ‚л § Є®­зЁ«Ё а Ў®вг б ­Ё¬, зв®Ўл Ё§ЎҐ¦ вм ­ аг襭ЁҐ бЁб⥬­®Ј® ЇаҐ¤Ґ« а §¬Ґа Є®«ЁзҐб⢠ᥣ¬Ґ­в®ў ®ЎйҐ© Ї ¬пвЁ. ‚맮ўл exit Ё exec ®вЄ«оз в ᥣ¬Ґ­вл Ї ¬пвЁ, ­® ­Ґ ®бў®Ў®¦¤пв Ёе.

‘¬®ваЁ shmctl man-бва ­Ёжг ¤«п ®ЇЁб ­Ёп ¤агЈЁе ®ЇҐа жЁ©, Є®в®алҐ ¬®¦­® ўлЇ®«­пвм б ᥣ¬Ґ­в ¬Ё ®ЎйҐ© Ї ¬пвЁ.

ЏаЁ¬Ґа Їа®Ја ¬¬л

Џа®Ја ¬¬ «ЁбвЁ­Ј 5.1 Ё««обваЁагҐв ЁбЇ®«м§®ў ­ЁҐ ®ЎйҐ© Ї ¬пвЁ.

Љ®¬ ­¤ ipcs ЇаҐ¤®бв ў«пҐв Ё­д®а¬ жЁо ®в­®бЁвҐ«м­® б।бвў ў§ Ё¬®¤Ґ©бвўЁп Їа®жҐбб®ў, ўЄ«оз п ®ЎйЁҐ ᥣ¬Ґ­вл Ї ¬пвЁ. €бЇ®«м§г©вҐ д« Ј -m , зв®Ўл Ї®«гзЁвм Ё­д®а¬ жЁо ®Ў ®ЎйҐ© Ї ¬пвЁ. Ќ ЇаЁ¬Ґа, нв®в Є®¤ Ё««обваЁагҐв з⮠ᥣ¬Ґ­в ®ЎйҐ© Ї ¬пвЁ, Їа®­г¬Ґа®ў ­­л© 1627649, ­ 室Ёвбп ў ЁбЇ®«м§®ў ­ЁЁ:

…б«Ё нв®в ᥣ¬Ґ­в Ї ¬пвЁ Ўл« ®иЁЎ®з­® ®бв ў«Ґ­ Їа®Ја ¬¬®©, ўл ¬®¦ҐвҐ ЁбЇ®«м§®ў вм Є®¬ ­¤г ipcrm , зв®Ўл г¤ «Ёвм ҐЈ®.

‡ Ё Їа®вЁў

CҐЈ¬Ґ­вл ®ЎйҐ© Ї ¬пвЁ Ї®§ў®«пов ®бгйҐбвў«пвм Ўлбваго ¤ўг­ Їа ў«Ґ­­го бўп§м б।Ё «оЎ®Ј® зЁб« Їа®жҐбб®ў. Љ ¦¤л© Ї®«м§®ў вҐ«м ¬®¦Ґв Ё зЁв вм Ё ЇЁб вм, ­® Їа®Ја ¬¬ ¤®«¦­ гбв ­®ўЁвм Ё б«Ґ¤®ў вм ­ҐЄ®в®а®¬г Їа®в®Є®«г ¤«п в®Ј®, зв®Ўл ЇаҐ¤®вўа вЁвм гб«®ўЁп Ј®­ЄЁ вЁЇ ЇҐаҐ§ ЇЁбЁ Ё­д®а¬ жЁЁ ЇаҐ¦¤Ґ, 祬 ®­ Їа®зЁв Ґвбп. Љ ᮦ «Ґ­Ёо, Linux бва®Ј® ­Ґ Ј а ­вЁагҐв нЄбЄ«о§Ёў­л© ¤®бвгЇ ¤ ¦Ґ Ґб«Ё ўл ᮧ¤ ¤ЁвҐ ­®ўл© ®ЎйЁ© ᥣ¬Ґ­в б IPC_PRIVATE .

Читать еще:  Удаленное подключение к linux

Ља®¬Ґ в®Ј®, ¤«п в®Ј® зв®Ў ­ҐбЄ®«мЄ® Їа®жҐбб®ў ¬®Ј«Ё ЁбЇ®«м§®ў вм ®Ўйго Ї ¬пвм, ®­Ё ¤®«¦­л ЇаЁ­пвм ¬Ґал, зв®Ўл ­Ґ ЁбЇ®«м§®ў вм ®¤Ё­ Ё в®в ¦Ґ Є«оз.

Разделяемая память, семафоры и очереди сообщений в ОС Linux

Разделяемая память

Каналы и сокеты являются удобными средствами обмена информацией между процессами, но их использование при интенсивном обмене или обмене объемными данными приводит к значительным накладными расходам. Разделяемая память является специализированным средством взаимодействия, имеющим минимальные издержки использования.

В листинге ниже при помощи команды ipcs показаны созданные в системе сегменты разделяемой памяти, массивы семафоров и очереди сообщений — средства межпроцессного взаимодействия svipc, «унаследованные» Linux от W:[UNIX System V].

Экземпляры средств System VIPC идентифицируются при помощи глобально уникальных ключей, или локальных идентификаторов shmid (shared memory identifier), semid (semaphore identifier) и msqid (message queue identifier), и сродни файлам имеют владельцев и права доступа.

Идентификаторы IPC (сродни индексным и файловым дескрипторам файлов) изменяются при пересоздаиии/переоткрытии экземпляра, а ключи IPC (подобно именам файлов) — нет.

Разделяемая память, очереди сообщений и семафоры (System V IPC)

$ ipcs

—— Сегменты совм. исп. памяти ——
ключ shmid владелец права байты nattch состояние
0x00000000 11567165 fitz 600 393216 2 назначение
0X06000000 10944514 fitz 700 1694060 2 назначение
6×06000606 11206666 fitz 600 393216 2 назначение

—— Массивы семафоров ——
ключ semid владелец права nsems

—— Очереди сообщений ——
ключ msqid владелец права исп. байты сообщения

Разделяемая память System VIPC реализуется ядром на основе механизма страничного отображения при помощи совместного использования страничных кадров страницами разных процессов.

При помощи системного вызова shmget один из взаимодействующих процессов создает сегмент памяти, состоящий из страничных кадров без отображения на какой-либо файл. Впоследствии кадры этого сегмента при помощи системного вызова shmat (shared memory attach) отображаются на страницы всех взаимодействующих процессов, за счет чего эти процессы и используют выделенную память совместно.

Иллюстрация применения разделяемой памяти приведена в листинге ниже, где сегмент разделяемой памяти с идентификатором 842138010 был создан (cpid, creator pid) процессом PID=8636 программы Х-клиента skype, а последнее обращение к нему (lpid, last operation pid) осуществлялось процессом PID=1461 программы X-сервера Xorg.

В данном конкретном случае X-клиент и X-сервер для эффективного обмена значительными объемами растровых изображений используют расширение X-протокола W: [MIT-SHM], основанное на использовании разделяемой памяти.

Разделяемая память (System V IPC)

—— Shared Memory Creator/Last-op PIDs ——
shmid владелец cpid ipid
11567105 fitz 16738 31382
10944514 fitz 4207 1461
8421380 fitz 8636 1461

$ dc -e 16ol0i8421380p

$ ps -fp 16738,31382,4207,1461,8636

UID PID PPID C STIME TTY TIME CMD
root 1461 1410 0 Feb22 tty7 01:23:02 /usr/bin/X :0 -auth /var/run/lig
fitz 4207 1 0 Feb26 ? 00:05:52 /usr/lib/virtualbox/VirtualBox
fitz 8636 1 1 Feb26 ? 00:39:15 skype
fitz 16738 1 1 Feb27 ? 00:20:35 /usr/lib/chromium-browser/chromi

99e23000 2176K rw-s- [ shmld=0x838005 ]
9a043000 3828K rw-s- [ shmld=0x830006 ]
9cc2f000 484K rw-s- [ shnld=0x828007 ]
9f541000 384K rw-s- [ shnlct=0x808004 ]
bf905000 132K rw— [ stack ]
total 632708K

$ sudo pmap
1461: /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch …

b5a5a000 384K rw-s- [ shmid=0xb28003 ]

b5abaeoe 384K rw-s- [ shmid=0x808004 ]

b5b3e000 384K rw-s- [ shmid=0xab000a ]
bfcd9000 144K rw— [ stack ]
total 107220K

Анализ карт памяти взаимодействующих процессов при помощи команды pmap подтверждает, что Страничные кадры сегмента разделяемой s памяти 842138016 (80800416) были отображены на страницы обоих взаимодействующих процессов по разным виртуальным адресам.

Еще один вариант реализации разделяемой памяти, пришедший в Linux из W:[BSD], основывается на «разделяемом» (shared) отображении одного файла в память разных процессов при помощи «штатного» механизма mmap. В листинге ниже показан типичный пример использования совместного отображения файла /var/cache/nscd/hosts в память процесса PID = 14566, nscd (name service cache daemon) и многих других процессов, пользующихся его услугами.

Служба имен (name service) предназначена для извлечения свойств различных каталогизируемых сущностей по их имени. Например, по имени интернет-узла из каталога системы доменных имен DNS служба имен извлекает IP-адрес этого узла, и наоборот, по IP-адресу — имя.

При большом количестве повторяющихся запросов к службе имен в течение промежутка времени, в который изменения запрашиваемой информации в соответствующем каталоге объектов не происходит, «бесполезные» повторные запросы к каталогу могут быть сокращены при помощи сохранения и использования предыдущих ответов (кэширования), чем и занимается демон nscd.

В частности, ответы из DNS сохраняются, процессом nscd в страничных кадрах памяти отображенного файла /var/cache/nscd/hosts, а остальные процессы совместно их используют, отображая тот же файл в страницы своей памяти.

Разделяемая память (BSD)

$ sudo fuser -v /var/cache/nscd/hosts

ПОЛЬЗ-ЛЬ PID ДОСТУП КОМАНДА
/var/cache/nscd/hosts:
root 14566 F…m nscd
fitz 16724 ….m ubuntu-geoip-pr
fitz 16738 ….m chromium-browse

fitz 15895 …m unity-scope-vid

fitz 8636 …m skype

$ sudo pmap 14566

14566: /usr/sbin/nscd
b1240000 32768K rw-s- /var/cache/nscd/hosts
bf8c5000 132K rw— [stack ]
total 153556K

$ pmap 8636

8636: skype
ab21e000 212K r—s- /var/cache/nscd/hosts
bf905000 132K rw— [ stack ]
total 632708K

Организация межпроцессного взаимодействия при помощи разделяемой памяти на основе «штатного» механизма отображения файлов в память процессов имеет один значительный недостаток. Так как изменяемые страничные кадры такого общего сегмента памяти требуют сохранения в дисковый файл, то производительность взаимодействия ограничивается операциями дискового ввода-вывода, а не скоростью работы оперативной памяти.

В примере с демоном nscd этого вполне достаточно, тем более что создаваемый им кэш все равно должен сохраняться при перезагрузках.

В случаях, когда взаимодействие процессов требует максимальной производительности, разделяемая память на основе отображения дисковых файлов в память является не лучшим механизмом. Элегантное решение данной проблемы используется в Linux-реализации разделяемой памяти стандарта POSIX, что проиллюстрировано в листинге ниже.

Псевдофайловая система tmpfs специально придумана для «временного» размещения файлов непосредственно в оперативной памяти, что в совокупности со «штатным» механизмом их отображения в память взаимодействующих процессов и дает желаемые характеристики производительности.

Разделяемая память (POSIX)

$ find mnt /dev/shn
TARGET SOURCE FSTYPE OPTIONS
/rw/shm tmpfs rw, nosuid, nodev, relatime

$ ls -l /dev/shm

lrwxrwxrwx 1 root root 8 нояб 19 09:50 /dev/shn -> /run/shm

$ sudo fuser -v /dev/shm/*
ПОЛЬЗ-ЛЬ PID ДОСТУП КОМАНДА
/run/shm/pulse-shm-2012073053:
fitz 16738 ….m chromium-browse

/run/shm/pulse-shm-2024923292:
fitz 2907 ….m pulseaudio
fitz 8636 ….m skype

$ pmap 8636

8636: skype
93cee000 65540K rw-s- /run/shm/pulse-shm-2024923292
bf905000 132K rw— [ stack ]
total 632708K

$ pmap 2907
2907: /usr/bin/pulseaudio — start — log-target=syslog
ad4ff000 65540K r—s- /run/shm/pulse-shm-2024923292
ad5a5000 64K rw-s- /dev/snd/pcmC0D0c
b15ес000 64K rw-s- /dev/snd/pcnC0O0p
bfel5000 132K rw— [ stack ]
total 167156K

В примере из листинга выше показано, как разделяемую память POSIX использует звуковая служба pulseaudio, позволяющая осуществлять совместный (мультиплексированный) доступ приложений к устройствам аудиоввода и аудиовывода /dev/snd/*.

Семафоры и очереди сообщений

Разделяемая память требует синхронизации действий процессов из-за эффекта гонки (race), возникающего между конкурентными, выполняющимися параллельно процессами. Для синхронизации процессов при совместном доступе к разделяемой памяти и прочим разделяемым ресурсам предназначено еще одно специализированное средство их взаимодействия — семафоры.

В большинстве случаев семафорами System V или POSIX пользуются многопроцессные сервисы, такие как, например, SQL-сервер postgres, который синхронизует доступ своих параллельных процессов к сегментам их общей памяти.

Семафоры (System V IPC)

——- Сегменты совм. исп. памяти ——
ключ shmid владелец права байты nattch состояние
0х0052е2с1 378241026 postgres 600 30482432 4

—— Массивы семафоров ——
ключ shmid владелец права nsems

0х0052е2с1 1081344 postgres 600 17
0х0052е2с2 1114113 postgres 600 17
0х0052е2сЗ 1146882 postgres 600 17
0х0052е2с4 1179651 postgres 600 17
0х0052е2с5 1212420 postgres 600 17
0х0052е2с6 1245189 postgres 600 17
0х0052е2с7 1277958 postgres 600 17

Очереди сообщений являются средствами взаимодействия между процессами, реализующими еще один интерфейс передачи сообщений (message passing inerface), подобно каналам и сокетам. По своей природе они похожи на дейтаграммный SOCK_DGRAM режим передачи поверх именованных локальных сокетов unix.

Основное отличие очередей сообщений от сокетов заключается в том, что время их жизни не ограничивается временем существования процессов, которые их создали. На практике очереди сообщений являются настолько малораспространенными, что их иллюстрация на среднестатистической инсталляции Linux практически невозможна.

Linux: типы памяти

Виртуальная память (Virtual Memory)

В современных операционных системах каждый процесс выполняется в собственном выделенном ему участке памяти. Вместо отображения (mapping) адресов памяти непосредственно на физические адреса, операционная система работает как некий абстрактный слой, создавая виртуальное адресное пространство для каждого процесса. Процесс отображение адресов между физической памятью и виртуальной памятью выполняется процессором с использованием «таблицы трансляции» (translation table) (или «таблица страниц«, или «адресная таблица«, «таблица перевода«) для каждого процесса, которая поддерживается ядром системы (каждый раз, когда ядро изменяет процесс, выполняющийся процессором, он изменяет адресная таблицу этого процессора).

Концепция виртуальной памяти имеет несколько целей. Во-первых, она осуществляет изоляцию процессов. Процесс в своём адресном пространстве получает доступ памяти только как к адресам виртуальной памяти. Соответственно, он имеет доступ к данным, которые предварительно были отображены в его собственное виртуальное пространство, и не имеет доступа к памяти других процессов (если память или часть памяти другого процесса не является общей (shared memory)).

Вторая цель — абстракция физической памяти. Ядро может изменять адреса физической памяти, на которую отображена виртуальная память. Кроме того, ядро может вообще не выделять физическую память процессу, пока она действительно не понадобится. Так же, ядро может переместить часть памяти в swap , если она не используется продолжительное время. Всё вместе это даёт большую свободу ядру, и единственным ограничением для него является то, что когда процесс обращается к участку памяти — он должен найти там ту же информацию, которую он записал туда ранее.

Третья цель — возможность выделения адресов объектам, которые ещё не загружены в память. Это основной принцип, лежащий в основе вызова mmap() и отображения файлов в память (file-backend память). Вы можете выделить адрес в памяти для файла, и к нему можно будет обращаться как к любому объекту в памяти. Это очень полезная абстракция, которая помогает упростить код приложений и, в системах х64, и у вас имеется огромное пространство виртуальных адресов, в которое вы можете отобразить хоть всё содержимое вашего жёсткого диска.

Читать еще:  Ошибка crc при установке игры

Четвёртая цель использования виртуальной памяти — разделение (sharing) памяти для совместного использования процессами. Так как ядро знает, что процесс загружает в память, оно может избежать повторной загрузки объектов, и выделить новые адреса виртуальной памяти для другого процесса, которые будут отображены на те же адреса физической памяти, что и у другого процесса.

Результатом использования «разделяемой памяти» является появление механизма COW (copy-on-write): когда два процесса используют одну и ту же информацию, но один из них изменяет её и при этом второй процесс не имеет доступа на чтение изменившихся данных, ядро выполняет копирование этих данных. Недавно операционная система так же получила возможность определять идентичные данные в разлиных адресах памяти и автоматически отображать их на один и тот же адрес физической памяти. В Linux это называется KSM (Kernel SamePage Merging)

Наиболее часто используемым случаем COW является fork() . В Unix-like системах fork() является системным вызовом, который создаёт новый процесс методом копирования текущего. По кончании выполнения fork() , оба процесса продолжают свою работу с того же состояния, с теми же открытыми файлами и памятью. Благодаря COW, fork() не дублирует всю память процесса, когда «форкает» его, а использует новые адреса памяти только для тех данных, которые изменились родительским или дочерним процессом.

Кроме того, когда вызов fork() создаёт копию («снимок«, snapshot) памяти процесса — он потребляет на это очень мало системных ресурсов. Поэтому, если вы хотите выполнить какие-то операции над памятью процесса без риска потери «почвы под ногами», и при этом вы хотите избежать дорогостоящих (в плане ресурсов системы) действий или каких-то механизмов блокировок, которые могут содержать или приводить к ошибкам — просто используйте fork() , выполните вашу задачу и передайте рузультат её выполнения обратно к родительскому процессу (с помощью кода возврата, файла, через разделяемую память, каналы ( pipe ) и т.д.).

Этот механизм отлично работает, пока результаты выполнения задачи выполняются достаточно быстро, что бы большая часть памяти между родительским и дочерними процессами оставалась разделяемой (общей). Кроме того, это поможет писать более простой и читаемый код, так как все сложные задачи будут скрыты в ядре операционной системы, в коде системы виртуальной памяти, а не в вашем.

Страницы (pages)

Виртуальная память разделена на страницы. Размер одной страницы (прим.: не путайте с блоками (block),которые относятся к данным жесткого диска, тогда как страницы — к памяти) определяется процессором и обычно равен 4 КБ (килобайтам). Это означает, что управление памятью выполняется на уровне страниц, а не битах-байтах и т.д. Когда вы запрашиваете память у системы — ядро выделяет вам одну или более страниц, когда вы особождатете память — вы освобождаете одну или более страниц памяти.

Для каждой выделенной (allocated) страницы ядро устанавливает набор прав доступа (как с обычными файлами в файловой системе) — страница может быть доступна на чтение (readable), запись (writable) и/или выполнение (executable). Эти права доступа устанавливаются либо во время отображения (выделения) памяти, либо с помощью системного вызова mprotect() уже после выделения. Страницы, которые ещё не выделены недоступны. Когда вы попытаетесь выполнить недопустимое действие над страницей памяти (например — считать данные со страницы, у которой не установлено право на чтение) — вы вызовете исключение Segmentation Fault .

Типы памяти (memory types)

Не вся память, выделенная в виртуальном пространстве, одинаковая. Мы можем классифицировать память по двум «осям»: первая — является ли память частной (private), т.е. специфичной для процесса, или общей (shared), и вторая ось — является ли память file-backed или нет (в таком случае — она является «анонимной» (anonymous) памятью). Таким образом — мы можем создать 4 класса памяти:

Interprocess communication using POSIX Shared Memory in Linux

1.0 Shared Memory

Shared memory is the fastest method of interprocess communication (IPC) under Linux and other Unix-like systems. The system provides a shared memory segment which the calling process can map to its address space. After that, it behaves just like any other part of the process’s address space.

2.0 Why is shared memory the fastest IPC mechanism?

If we look at the other IPC mechanisms like message queue or the older mechanisms like the pipe or the fifo, the work required for passing message involves, first copying the message from the address space of the first process to the kernel space via a send-like system call and, then, copying the message from the kernel space to the address space of the second process during a receive-like call. In the case of shared memory, the shared memory segment is mapped to the address space of both processes. As soon as the first process writes data in the shared memory segment, it becomes available to the second process. This makes shared memory faster than other mechanisms and is, in fact, the fastest way of passing data between two processes on the same host system.

3.0 System V and POSIX Shared Memory Calls

For each of the IPC mechanisms, there are two sets of calls, the traditional System V calls and the newer POSIX calls. In this post, we will look at the POSIX shared memory calls. Example programs for server and client processes that communicate via POSIX shared memory are given near the end of this post.

4.0 POSIX Shared Memory Calls

The POSIX shared memory calls seem to be based on the UNIX philosophy that if you do Input/Output operations on an object, that object has to be a file. So, since we do read and write to a POSIX shared memory object, the latter is to be treated as a file. A POSIX shared memory object is a memory-mapped file. POSIX shared memory files are provided from a tmpfs filesystem mounted at /dev/shm . The individual shared memory files are created using the shm_open system call under /dev/shm . There are just two specialized POSIX shared memory system calls, shm_open and shm_unlink , which are analogous to open and unlink system calls for files. Other operations on POSIX shared memory are done using the ftruncate , mmap and munmap system calls for files. A program using POSIX shared memory calls needs to be linked with -lrt .

4.1 shm_open

shm_open is like the open system call for files. It opens a POSIX shared memory object and makes it available to the calling process via the returned file descriptor. The first parameter, name, is the name of the shared memory object and is of the form /somename, that is, it is a null-terminated string of a maximum of NAME_MAX characters, and, its first character is a slash and none of the other characters can be a slash. oflag is a bit mask constructed by OR-ing either O_RDONLY or O_RDWR with one or more of the following flags. O_CREAT creates the shared memory object if it does not exist. And, if it creates the object, the last nine bits of the third parameter, mode are taken for permissions except that the bits set in the file mode creation mask are cleared for the object. Also, if the shared memory object is created, the owner and group ids of the object are set the corresponding effective ids of the calling process. A newly created shared memory object is of size zero bytes. It can be made of the desired size by using the ftruncate system call. If O_EXCL flag is used together with the O_CREAT flag, and the shared memory object for the name already exists, shm_open fails and errno is set to EEXIST . There is another flag, O_TRUNC , which if specified, truncates the shared memory object, if it already exists, to size zero bytes. On success, shm_open returns the file descriptor for the shared memory object. If shm_open fails, it returns -1 and errno is set to the cause of the error.

4.2 shm_unlink

shm_unlink removes the previously created POSIX shared memory object. The name is the name of the shared memory object as described under shm_open , above.

5.0 Other System Calls used in POSIX Shared Memory Operations

5.1 ftruncate

The ftruncate system call makes the object referred to by the file descriptor, fd, of size length bytes. When a POSIX shared memory is created, it is of size zero bytes. Using ftruncate , we can make the POSIX shared memory object of size length bytes. ftruncate returns zero on success. In case of error, ftruncate returns -1 and errno is set to the cause of the error.

5.2 mmap

With the mmap system call, we can map a POSIX shared memory object to the calling process’s virtual address space. addr specifies the address at which it should be mapped. In most cases, we do not care at what address mapping is done and a value of NULL for addr should suffice. length is the length of shared memory object that should be mapped. To keep things simple, we will map the whole object and length for us will be the length of the shared memory object. prot can have the values, PROT_EXEC , PROT_READ , PROT_WRITE and PROT_NONE . PROT_EXEC means that the mapped pages may be executed and PROT_NONE means that the mapped pages may not be accessed. These two values do not make sense for a shared memory object. So we will use PROT_READ | PROT_WRITE value for prot. There are many flags but the only one meaningful for shared memory is MAP_SHARED , which means that the updates to the mapped shared memory are visible to all other processes immediately. fd is, of course, the file descriptor for the shared memory received from an earlier shm_open call. offset is the location in the shared memory object at which the mapping starts; we will use the value zero for offset and map the shared memory object starting right from the beginning. On success, mmap returns the pointer to the location where the shared memory object has been mapped. In case of error, MAP_FAILED , which is, (void *) -1 , is returned and errno is set to the cause of the error.

Читать еще:  Код ошибки 0x00000e9

5.3 munmap

munmap unmapps the shared memory object at location pointed by addr and having size, length. On success, munmap returns 0. In case of error, munmap returns -1 and errno is set to the cause of the error.

6.0 An example: System Logger

The System Logger process creates a POSIX shared memory object and maps it to its address space. Clients also map the shared memory object to their address spaces. When a client wants to log a message, it creates a string in the format and writes the string in the shared memory object. The logger reads strings from the shared memory object, one by one, and writes them in a log file in the chronological order.

The server code is,

And, the client code is,

We can compile and run the server and a client as below.

Разделяемая память, семафоры и очереди сообщений в ОС Linux

Разделяемая память

Каналы и сокеты являются удобными средствами обмена информацией между процессами, но их использование при интенсивном обмене или обмене объемными данными приводит к значительным накладными расходам. Разделяемая память является специализированным средством взаимодействия, имеющим минимальные издержки использования.

В листинге ниже при помощи команды ipcs показаны созданные в системе сегменты разделяемой памяти, массивы семафоров и очереди сообщений — средства межпроцессного взаимодействия svipc, «унаследованные» Linux от W:[UNIX System V].

Экземпляры средств System VIPC идентифицируются при помощи глобально уникальных ключей, или локальных идентификаторов shmid (shared memory identifier), semid (semaphore identifier) и msqid (message queue identifier), и сродни файлам имеют владельцев и права доступа.

Идентификаторы IPC (сродни индексным и файловым дескрипторам файлов) изменяются при пересоздаиии/переоткрытии экземпляра, а ключи IPC (подобно именам файлов) — нет.

Разделяемая память, очереди сообщений и семафоры (System V IPC)

$ ipcs

—— Сегменты совм. исп. памяти ——
ключ shmid владелец права байты nattch состояние
0x00000000 11567165 fitz 600 393216 2 назначение
0X06000000 10944514 fitz 700 1694060 2 назначение
6×06000606 11206666 fitz 600 393216 2 назначение

—— Массивы семафоров ——
ключ semid владелец права nsems

—— Очереди сообщений ——
ключ msqid владелец права исп. байты сообщения

Разделяемая память System VIPC реализуется ядром на основе механизма страничного отображения при помощи совместного использования страничных кадров страницами разных процессов.

При помощи системного вызова shmget один из взаимодействующих процессов создает сегмент памяти, состоящий из страничных кадров без отображения на какой-либо файл. Впоследствии кадры этого сегмента при помощи системного вызова shmat (shared memory attach) отображаются на страницы всех взаимодействующих процессов, за счет чего эти процессы и используют выделенную память совместно.

Иллюстрация применения разделяемой памяти приведена в листинге ниже, где сегмент разделяемой памяти с идентификатором 842138010 был создан (cpid, creator pid) процессом PID=8636 программы Х-клиента skype, а последнее обращение к нему (lpid, last operation pid) осуществлялось процессом PID=1461 программы X-сервера Xorg.

В данном конкретном случае X-клиент и X-сервер для эффективного обмена значительными объемами растровых изображений используют расширение X-протокола W: [MIT-SHM], основанное на использовании разделяемой памяти.

Разделяемая память (System V IPC)

—— Shared Memory Creator/Last-op PIDs ——
shmid владелец cpid ipid
11567105 fitz 16738 31382
10944514 fitz 4207 1461
8421380 fitz 8636 1461

$ dc -e 16ol0i8421380p

$ ps -fp 16738,31382,4207,1461,8636

UID PID PPID C STIME TTY TIME CMD
root 1461 1410 0 Feb22 tty7 01:23:02 /usr/bin/X :0 -auth /var/run/lig
fitz 4207 1 0 Feb26 ? 00:05:52 /usr/lib/virtualbox/VirtualBox
fitz 8636 1 1 Feb26 ? 00:39:15 skype
fitz 16738 1 1 Feb27 ? 00:20:35 /usr/lib/chromium-browser/chromi

99e23000 2176K rw-s- [ shmld=0x838005 ]
9a043000 3828K rw-s- [ shmld=0x830006 ]
9cc2f000 484K rw-s- [ shnld=0x828007 ]
9f541000 384K rw-s- [ shnlct=0x808004 ]
bf905000 132K rw— [ stack ]
total 632708K

$ sudo pmap
1461: /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch …

b5a5a000 384K rw-s- [ shmid=0xb28003 ]

b5abaeoe 384K rw-s- [ shmid=0x808004 ]

b5b3e000 384K rw-s- [ shmid=0xab000a ]
bfcd9000 144K rw— [ stack ]
total 107220K

Анализ карт памяти взаимодействующих процессов при помощи команды pmap подтверждает, что Страничные кадры сегмента разделяемой s памяти 842138016 (80800416) были отображены на страницы обоих взаимодействующих процессов по разным виртуальным адресам.

Еще один вариант реализации разделяемой памяти, пришедший в Linux из W:[BSD], основывается на «разделяемом» (shared) отображении одного файла в память разных процессов при помощи «штатного» механизма mmap. В листинге ниже показан типичный пример использования совместного отображения файла /var/cache/nscd/hosts в память процесса PID = 14566, nscd (name service cache daemon) и многих других процессов, пользующихся его услугами.

Служба имен (name service) предназначена для извлечения свойств различных каталогизируемых сущностей по их имени. Например, по имени интернет-узла из каталога системы доменных имен DNS служба имен извлекает IP-адрес этого узла, и наоборот, по IP-адресу — имя.

При большом количестве повторяющихся запросов к службе имен в течение промежутка времени, в который изменения запрашиваемой информации в соответствующем каталоге объектов не происходит, «бесполезные» повторные запросы к каталогу могут быть сокращены при помощи сохранения и использования предыдущих ответов (кэширования), чем и занимается демон nscd.

В частности, ответы из DNS сохраняются, процессом nscd в страничных кадрах памяти отображенного файла /var/cache/nscd/hosts, а остальные процессы совместно их используют, отображая тот же файл в страницы своей памяти.

Разделяемая память (BSD)

$ sudo fuser -v /var/cache/nscd/hosts

ПОЛЬЗ-ЛЬ PID ДОСТУП КОМАНДА
/var/cache/nscd/hosts:
root 14566 F…m nscd
fitz 16724 ….m ubuntu-geoip-pr
fitz 16738 ….m chromium-browse

fitz 15895 …m unity-scope-vid

fitz 8636 …m skype

$ sudo pmap 14566

14566: /usr/sbin/nscd
b1240000 32768K rw-s- /var/cache/nscd/hosts
bf8c5000 132K rw— [stack ]
total 153556K

$ pmap 8636

8636: skype
ab21e000 212K r—s- /var/cache/nscd/hosts
bf905000 132K rw— [ stack ]
total 632708K

Организация межпроцессного взаимодействия при помощи разделяемой памяти на основе «штатного» механизма отображения файлов в память процессов имеет один значительный недостаток. Так как изменяемые страничные кадры такого общего сегмента памяти требуют сохранения в дисковый файл, то производительность взаимодействия ограничивается операциями дискового ввода-вывода, а не скоростью работы оперативной памяти.

В примере с демоном nscd этого вполне достаточно, тем более что создаваемый им кэш все равно должен сохраняться при перезагрузках.

В случаях, когда взаимодействие процессов требует максимальной производительности, разделяемая память на основе отображения дисковых файлов в память является не лучшим механизмом. Элегантное решение данной проблемы используется в Linux-реализации разделяемой памяти стандарта POSIX, что проиллюстрировано в листинге ниже.

Псевдофайловая система tmpfs специально придумана для «временного» размещения файлов непосредственно в оперативной памяти, что в совокупности со «штатным» механизмом их отображения в память взаимодействующих процессов и дает желаемые характеристики производительности.

Разделяемая память (POSIX)

$ find mnt /dev/shn
TARGET SOURCE FSTYPE OPTIONS
/rw/shm tmpfs rw, nosuid, nodev, relatime

$ ls -l /dev/shm

lrwxrwxrwx 1 root root 8 нояб 19 09:50 /dev/shn -> /run/shm

$ sudo fuser -v /dev/shm/*
ПОЛЬЗ-ЛЬ PID ДОСТУП КОМАНДА
/run/shm/pulse-shm-2012073053:
fitz 16738 ….m chromium-browse

/run/shm/pulse-shm-2024923292:
fitz 2907 ….m pulseaudio
fitz 8636 ….m skype

$ pmap 8636

8636: skype
93cee000 65540K rw-s- /run/shm/pulse-shm-2024923292
bf905000 132K rw— [ stack ]
total 632708K

$ pmap 2907
2907: /usr/bin/pulseaudio — start — log-target=syslog
ad4ff000 65540K r—s- /run/shm/pulse-shm-2024923292
ad5a5000 64K rw-s- /dev/snd/pcmC0D0c
b15ес000 64K rw-s- /dev/snd/pcnC0O0p
bfel5000 132K rw— [ stack ]
total 167156K

В примере из листинга выше показано, как разделяемую память POSIX использует звуковая служба pulseaudio, позволяющая осуществлять совместный (мультиплексированный) доступ приложений к устройствам аудиоввода и аудиовывода /dev/snd/*.

Семафоры и очереди сообщений

Разделяемая память требует синхронизации действий процессов из-за эффекта гонки (race), возникающего между конкурентными, выполняющимися параллельно процессами. Для синхронизации процессов при совместном доступе к разделяемой памяти и прочим разделяемым ресурсам предназначено еще одно специализированное средство их взаимодействия — семафоры.

В большинстве случаев семафорами System V или POSIX пользуются многопроцессные сервисы, такие как, например, SQL-сервер postgres, который синхронизует доступ своих параллельных процессов к сегментам их общей памяти.

Семафоры (System V IPC)

——- Сегменты совм. исп. памяти ——
ключ shmid владелец права байты nattch состояние
0х0052е2с1 378241026 postgres 600 30482432 4

—— Массивы семафоров ——
ключ shmid владелец права nsems

0х0052е2с1 1081344 postgres 600 17
0х0052е2с2 1114113 postgres 600 17
0х0052е2сЗ 1146882 postgres 600 17
0х0052е2с4 1179651 postgres 600 17
0х0052е2с5 1212420 postgres 600 17
0х0052е2с6 1245189 postgres 600 17
0х0052е2с7 1277958 postgres 600 17

Очереди сообщений являются средствами взаимодействия между процессами, реализующими еще один интерфейс передачи сообщений (message passing inerface), подобно каналам и сокетам. По своей природе они похожи на дейтаграммный SOCK_DGRAM режим передачи поверх именованных локальных сокетов unix.

Основное отличие очередей сообщений от сокетов заключается в том, что время их жизни не ограничивается временем существования процессов, которые их создали. На практике очереди сообщений являются настолько малораспространенными, что их иллюстрация на среднестатистической инсталляции Linux практически невозможна.

Ссылка на основную публикацию
Adblock
detector