Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² срСдС Linux. Π’Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 62

Автор Майкл ДТонсон

13.2.5. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° областСй памяти

Π’ Linux ΠΈ ΠΌΠ½ΠΎΠ³ΠΈΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… соврСмСнных ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСмах для областСй памяти ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ страничный ΠΎΠ±ΠΌΠ΅Π½ с диском (ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΠ»ΠΎΠ½ΡΡ‚ΡŒ, Ссли ΠΈΡ… Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ способом), ΠΊΠΎΠ³Π΄Π° Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π΄Π΅Ρ„ΠΈΡ†ΠΈΡ‚ памяти. На прилоТСния, Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊ ограничСниям внСшнСй синхронизации, ΠΌΠΎΠΆΠ΅Ρ‚ нСблагоприятно ΠΏΠΎΠ²Π»ΠΈΡΡ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ°, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΠ΄ΠΊΠ°Ρ‡ΠΊΠ° страниц ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² ΠžΠ—Π£, ΠΊΠΎΠ³Π΄Π° это Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ процСссу. Для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ надСТности Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Linux позволяСт процСссу Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ области памяти Π² ΠžΠ—Π£, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ эти синхронизации Π±ΠΎΠ»Π΅Π΅ прСдсказуСмыми. Π’ цСлях бСзопасности Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° памяти Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ процСссам с полномочиями ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ[87]. Если Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ области памяти смоТСт любой процСсс, Ρ‚ΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ нСисправный процСсс ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС ΠžΠ—Π£ систСмы ΠΈ привСсти Π΅Π΅ ΠΊ ΠΊΡ€Π°Ρ…Ρƒ. ΠžΠ±Ρ‰Π΅Π΅ количСство памяти, Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ процСссом, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Ρ‚ΡŒ ΠΏΡ€Π΅Π΄Π΅Π» использования RLIMIT_MEMLOCK (см. Π³Π»Π°Π²Ρƒ 10).

Для блокирования ΠΈ разблокирования областСй памяти ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ пСрСчислСнныС Π½ΠΈΠΆΠ΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹.

#include <sys/mman.h>


int mlock(caddr_t addr, size_t length);

int mlockall(int flags);

int munlock(caddr_t addr, size_t length);

int munlockall(void);

ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ², mlock(), Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ length Π±Π°ΠΉΡ‚, начиная с адрСса addr. Π—Π° ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· Π΄ΠΎΠ»ΠΆΠ½Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ полная страница памяти, поэтому mlock() фактичСски Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ всС страницы ΠΌΠ΅ΠΆΠ΄Ρƒ страницСй, содСрТащСй ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ адрСс, ΠΈ страницСй, содСрТащСй послСдний адрСс, Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ mlock() всС страницы, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ распространился Π²Ρ‹Π·ΠΎΠ², окаТутся Π² ΠžΠ—Π£.

Если процСссу Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС своС адрСсноС пространство, примСняСтся mlосkall(). АргумСнт flags ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ ΠΎΠ±ΠΎΠΈΡ… описанных Π½ΠΈΠΆΠ΅ Ρ„Π»Π°Π³ΠΎΠ², ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½Π΅Π½Π½Ρ‹Ρ… с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΡ‚ΠΎΠ²ΠΎΠ³ΠΎ "Π˜Π›Π˜".

MCL_CURRENT ВсС страницы, Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ находящиСся Π² адрСсном пространствС процСсса, Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² ΠžΠ—Π£. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π²Ρ‹Π·ΠΎΠ²Π° mlockall() ΠΎΠ½ΠΈ всС Π±ΡƒΠ΄ΡƒΡ‚ Π² ΠžΠ—Π£. MCL_FUTURE ВсС страницы, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ ΠΊ адрСсному пространству процСсса, Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² ΠžΠ—Π£.

Π Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ памяти β€” это ΠΏΠΎΡ‡Ρ‚ΠΈ Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ Π΅Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Если процСсс большС Π½Π΅ нуТдаСтся Π² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ памяти, munlockall() Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ всС Π΅Π³ΠΎ страницы. munlock() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚Π΅ ΠΆΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹, Ρ‡Ρ‚ΠΎ ΠΈ mlock(), ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ страницы, относящиСся ΠΊ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ области.

ΠœΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ страницы эквивалСнтно ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠΌΡƒ. Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ случаС ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² munlock() Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ страницы, ΠΏΠΎΠ΄ΠΏΠ°Π΄Π°ΡŽΡ‰ΠΈΠ΅ ΠΏΠΎΠ΄ Π΅Π³ΠΎ влияниС.

13.3. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ²

Π₯отя доступ ΠΊ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ Ρ„Π°ΠΉΠ»Ρƒ со стороны Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… процСссов β€” Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ΅ явлСниС, Π΄Π΅Π»Π°Ρ‚ΡŒ это слСдуСт остороТно. МногиС Ρ„Π°ΠΉΠ»Ρ‹ содСрТат слоТныС структуры Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ этих структур создаСт Ρ‚Π΅ ΠΆΠ΅ условия состязаний, Ρ‡Ρ‚ΠΎ ΠΈ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Ρ… сигналов ΠΈ областях совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ памяти.

БущСствуСт Π΄Π²Π° Ρ‚ΠΈΠΏΠ° блокирования Ρ„Π°ΠΉΠ»ΠΎΠ². НаиболСС распространСнноС β€” Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ядром ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅ осущСствляСтся. Π­Ρ‚ΠΎ просто соглашСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ всС процСссы, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ доступ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ. Π’Ρ‚ΠΎΡ€ΠΎΠΉ Ρ‚ΠΈΠΏ, ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ выполняСтся ядром. Когда процСсс Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„Π°ΠΉΠ» для записи, Π΄Ρ€ΡƒΠ³ΠΈΠ΅ процСссы, ΠΏΡ‹Ρ‚Π°ΡŽΡ‰ΠΈΠ΅ΡΡ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² Ρ„Π°ΠΉΠ», ΠΏΡ€ΠΈΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π΄ΠΎ снятия Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Π₯отя этот ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΌ, ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ‹Π½ΡƒΠΆΠ΄Π°Π΅Ρ‚ ядро ΡΠΎΠ²Π΅Ρ€ΡˆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ наличия Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ read() ΠΈ write(), сущСствСнно сниТая ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ этих систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма Linux прСдоставляСт Π΄Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° блокирования Ρ„Π°ΠΉΠ»ΠΎΠ²: Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ записСй.

13.3.1. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ простым ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ блокирования. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π½ΡƒΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΉΡΡ Π² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Ρ„Π°ΠΉΠ» Π΄Π°Π½Π½Ρ‹Ρ… ассоциируСтся с Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ. Когда Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» сущСствуСт, Ρ„Π°ΠΉΠ» Π΄Π°Π½Π½Ρ‹Ρ… считаСтся Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ, ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ процСссы Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΊ Π½Π΅ΠΌΡƒ доступа. Когда Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π½Π΅ сущСствуСт, процСсс создаСт Π΅Π³ΠΎ ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…. Π”ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° создания Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Π° (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ процСсс Π·Π° Ρ€Π°Π· ΠΌΠΎΠΆΠ΅Ρ‚ "Π²Π»Π°Π΄Π΅Ρ‚ΡŒ" Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ), этот ΠΌΠ΅Ρ‚ΠΎΠ΄ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ доступ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ со стороны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ИдСя довольно проста. Когда процСсс намСрСваСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ, ΠΎΠ½ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„Π°ΠΉΠ» ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

fd = open("somefile.lck", O_RDONLY, 0644);

if (fd >= 0) {

 close(fd);

 printf("Ρ„Π°ΠΉΠ» ΡƒΠΆΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½");

 return 1;

} else {

 /* Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π½Π΅ сущСствуСт, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ

    ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ */

 fd = open("somefile.lck", O_CREAT | O_WRONLY, 0644");

 if (fd < 0) {

  perror("ошибка ΠΏΡ€ΠΈ создании Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°");

  return 1;

 }

 /* ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ pid Π² Ρ„Π°ΠΉΠ» */

 close(fd);

}

Когда процСсс Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Ρ„Π°ΠΉΠ»Π°, ΠΎΠ½ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ unlink("somefile.lck") для снятия Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ.

НСсмотря Π½Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π²Ρ‹ΡˆΠ΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° выглядит ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ, ΠΎΠ½ позволяСт ΠΏΡ€ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°Ρ… нСскольким процСссам Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ», Π° ΠΈΠΌΠ΅Π½Π½ΠΎ этого ΠΈ слСдуСт ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ Π² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ. Если процСсс провСряСт сущСствованиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°, убСТдаСтся Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π½Π΅ сущСствуСт, ΠΈ прСрываСтся ядром, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΏΡ€ΠΎΡ‡ΠΈΠΌ процСссам, Ρ‚ΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс смоТСт Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ исходный процСсс создаст Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ». Π€Π»Π°Π³ O_EXCL для open() ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ созданиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹ΠΌ ΠΈ, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹ΠΌ ΠΎΡ‚ условия состязаний. ПослС установки O_EXCL Π²Ρ‹Π·ΠΎΠ² open() Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ΠΉ, Ссли Ρ„Π°ΠΉΠ» ΡƒΠΆΠ΅ сущСствуСт. Π­Ρ‚ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ созданиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ происходит Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅.

fd = open("somefile.lck", O_WRONLY | O_CREAT | O_EXCL, 0644);

if (fd < 0 && errno == EEXIST) {

 printf("Ρ„Π°ΠΉΠ» ΡƒΠΆΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½");

 return 1;

} else if (fd < 0) {

 perror("нСпрСдвидСнная ошибка ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ");

 return 1;

}

/* ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ pid Π² Ρ„Π°ΠΉΠ» */

close(fd);

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для блокирования ΡˆΠΈΡ€ΠΎΠΊΠΎΠ³ΠΎ ряда стандартных Ρ„Π°ΠΉΠ»ΠΎΠ² Linux, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠΎΡ€Ρ‚Ρ‹ ΠΈ Ρ„Π°ΠΉΠ» /etc/passwd. Π₯отя ΠΎΠ½ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ со ΠΌΠ½ΠΎΠ³ΠΈΠΌΠΈ прилоТСниями, ΠΈΠΌ присущи ΠΈ нСсколько ΡΠ΅Ρ€ΡŒΠ΅Π·Π½Ρ‹Ρ… нСдостатков.

β€’ Π’олько ΠΎΠ΄ΠΈΠ½ процСсс Π·Π° ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, прСдотвращая ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° нСсколькими процСссами. Если Ρ„Π°ΠΉΠ» обновляСтся Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΠΎ[88], Ρ‚ΠΎ процСссы, Ρ‡ΠΈΡ‚Π°ΡŽΡ‰ΠΈΠ΅ Ρ„Π°ΠΉΠ», ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ вопросы блокирования, Π½ΠΎ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ обновлСния слоТно ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ для слоТных Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… структур.

β€’ Π€Π»Π°Π³ O_EXCL Π½Π°Π΄Π΅ΠΆΠ΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… систСмах. Ни ΠΎΠ΄Π½Π° ΠΈΠ· сСтСвых Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… систСм, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… Linux, Π½Π΅ сохраняСт сСмантику O_EXCL ΠΌΠ΅ΠΆΠ΄Ρƒ нСсколькими машинами, Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΎΠ±Ρ‰ΠΈΠΉ Ρ„Π°ΠΉΠ»[89].

β€’ Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ являСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ; процСссы ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ», нСсмотря Π½Π° сущСствованиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ.

β€’ Π•сли процСсс, ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, Π°Π²Π°Ρ€ΠΈΠΉΠ½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» остаСтся. Если ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ процСсса сохранСн Π² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅, Π΄Ρ€ΡƒΠ³ΠΈΠ΅ процСссы ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ сущСствованиС Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ процСсса ΠΈ ΡΠ½ΡΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, Ссли Ρ‚ΠΎΡ‚ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ. Π­Ρ‚ΠΎ, ΠΎΠ΄Π½Π°ΠΊΠΎ, слоТная ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°, которая Π½Π΅ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚, Ссли ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссом ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅.

13.3.2. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° записСй

Π‘ Ρ†Π΅Π»ΡŒΡŽ прСодолСния ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, присущих Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»Π°ΠΌ, Π² System V ΠΈ BSD 4.3 Π±Ρ‹Π»Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° записСй, рСализуСмая с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² lockf() ΠΈ flock() соотвСтствСнно. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ POSIX ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ» Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ для Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ систСмный Π²Ρ‹Π·ΠΎΠ² fcntl(). Π₯отя Linux ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ всС Ρ‚Ρ€ΠΈ интСрфСйса, ΠΌΡ‹ обсудим Ρ‚ΠΎΠ»ΡŒΠΊΠΎ интСрфСйс POSIX, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сСйчас Π΅Π³ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ ΠΏΠΎΡ‡Ρ‚ΠΈ всС ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Unix. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, функция lockf() Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° ΠΊΠ°ΠΊ интСрфСйс для fcntl(), поэтому ΠΎΡΡ‚Π°Π²ΡˆΠ°ΡΡΡ Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°Π½Π½ΠΎΠ³ΠΎ обсуТдСния касаСтся ΠΎΠ±ΠΎΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ².

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π΄Π²Π° Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… отличия ΠΌΠ΅ΠΆΠ΄Ρƒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌΠΈ записСй ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записСй ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΊ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΉ части Ρ„Π°ΠΉΠ»Π°. НапримСр, процСсс А ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±Π°ΠΉΡ‚Ρ‹ с 50-Π³ΠΎ ΠΏΠΎ 200-ΠΉ Ρ„Π°ΠΉΠ»Π°, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π±Π°ΠΉΡ‚Ρ‹ с 2500-Π³ΠΎ ΠΏΠΎ 3000-ΠΉ Π±Π΅Π· ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π° Π΄Π²ΡƒΡ… Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ. ΠœΠ΅Π»ΠΊΠΎΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° нСскольким процСссам Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ». Π•Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ прСимущСство блокирования записСй Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π² ядрС, Π° Π½Π΅ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС. По ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ процСсса всС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ содСрТит, ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ΡΡ.