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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Linux ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 207

Автор Роббинс ΠΡ€Π½ΠΎΠ»ΡŒΠ΄

POSIX стандартизуСт лишь Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° доступна Π½Π° GNU/Linux, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π² рядС коммСрчСских систСм Unix, Π½ΠΎ Π΄Π΅Ρ‚Π°Π»ΠΈ Π²Π°Ρ€ΡŒΠΈΡ€ΡƒΡŽΡ‚. Π”Π°Π»Π΅Π΅ Π² Π΄Π°Π½Π½ΠΎΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ рассмотрим Π΄Π΅Ρ‚Π°Π»ΠΈ для GNU/Linux.

14.2.2. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° POSIX:

fcntl()
ΠΈ
lockf()

БистСмный Π²Ρ‹Π·ΠΎΠ²

fcntl()
(file control β€” ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠΌ) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ„Π°ΠΉΠ»Π°. (Π”Ρ€ΡƒΠ³ΠΎΠ΅ использованиС
fcntl()
Π±Ρ‹Π»ΠΎ описано Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 9.4.3 Β«Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°:
fcntl()
Β».) Он объявлСн ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

#include <unistd.h> /* POSIX */

#include <fcntl.h>

int fcntl(int fd, int cmd); /* Not relevant for file locking */

int fcntl(int fd, int cmd, long arg); /* Not relevant for file locking */

int fcntl(int fd, int cmd, struct flock *lock);

АргумСнты ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅:

fd
ДСскриптор Ρ„Π°ΠΉΠ»Π° для ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°.

cmd
Одна ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… констант, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π²
<fcntl.h>
. НиТС ΠΎΠ½ΠΈ описаны Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ.

lock
Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π°
struct flock
, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΡƒΡŽ Π½ΡƒΠΆΠ½Ρ‹ΠΉ Π±Π»ΠΎΠΊ.

14.2.2.1. ОписаниС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ осущСствлСниС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, Π΄Π°Π²Π°ΠΉΡ‚Π΅ исслСдуСм описаниС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС. Π­Ρ‚ΠΎ дСлаСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ структуры

struct flock
, которая описываСт Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… Π±Π°ΠΉΡ‚ΠΎΠ² ΠΈ Π²ΠΈΠ΄ Π½ΡƒΠΆΠ½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ POSIX ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ
struct lock
содСрТит Β«ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅Β» ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹. Π­Ρ‚ΠΎ позволяСт Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹ структуры. Из слСгка ΠΎΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ справочной страницы fcntl(3):

struct flock {

Β ...

Β short l_type; /* Π’ΠΈΠΏ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ: F_RDLCK, F_WRLCK, F_UNLCK */

Β short l_whence; /* Как интСрпрСтируСтся l_start:

Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  Β SEEK_SET, SEEK_CUR, SEEK_END */

Β off_t l_start; /* ΠΠ°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ΅ смСщСниС */

Β off_t l_len; /* Число Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… Π±Π°ΠΉΡ‚ΠΎΠ²;

Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  Β 0 ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΎΡ‚ Π½Π°Ρ‡Π°Π»Π° Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π° */

Β pid_t l_pid; /* PID Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ процСсса (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ F_GETLK) */

Β ...

};

ПолС

l_start
являСтся смСшСниСм Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π±Π°ΠΉΡ‚Π° Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ участка.
l_len
являСтся Π΄Π»ΠΈΠ½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ участка, Ρ‚. Π΅. ΠΎΠ±Ρ‰ΠΈΠΌ числом Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… Π±Π°ΠΉΡ‚ΠΎΠ².
l_whence
ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ мСсто Π² Ρ„Π°ΠΉΠ»Π΅, ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ отсчитываСтся
l_start
, значСния Ρ‚Π΅ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ для Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°
whence
Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
lseek()
(см Ρ€Π°Π·Π΄Π΅Π» 4.5 Β«ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ доступ: пСрСмСщСния Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„Π°ΠΉΠ»Π°Β»), ΠΎΡ‚ΡΡŽΠ΄Π° ΠΈ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ поля. Π­Ρ‚Π° структура самодостаточна: смСщСниС
l_start
ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅
l_whence
Π½Π΅ связаны с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ для чтСния ΠΈΠ»ΠΈ записи. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ΄Π° ΠΌΠΎΠ³ Π±Ρ‹ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

struct employee { /* Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ */ }; /* ОписаниС сотрудника */

struct flock lock; /* Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π±Π»ΠΎΠΊΠ° */

...

/* Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ структуру для ΡˆΠ΅ΡΡ‚ΠΎΠ³ΠΎ сотрудника */

lock.l_whence = SEEK_SET; /* ΠΠ±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ */

lock.l_start = 5 * sizeof(struct employee); /* Начало 6-ΠΉ структуры */

lock.l_len = sizeof(struct employee); /* Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ запись */

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ

SEEK_CUR
ΠΈΠ»ΠΈ
SEEK_END
, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ участки, начиная ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ смСщСния Π² Ρ„Π°ΠΉΠ»Π΅ ΠΈΠ»ΠΈ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π° соотвСтствСнно. Для этих Π΄Π²ΡƒΡ… случаСв
l_start
ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, ΠΏΠΎΠΊΠ° Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ΅ Π½Π°Ρ‡Π°Π»ΠΎ Π½Π΅ мСньшС нуля. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ послСднюю запись Π² Ρ„Π°ΠΉΠ»Π΅:

/* Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ запись послСднСго сотрудника */

lock.l_whence = SEEK_END; /* ΠžΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ EOF */

lock.l_start = -1 * sizeof (struct employee);

Β /* Начало послСднСй структуры */

lock.l_len = sizeof(struct employee); /* Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ запись */

Установка

l_len
Π² 0 являСтся особым случаСм. Он ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Ρ„Π°ΠΉΠ»Π° ΠΎΡ‚ Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ полоТСния, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
l_start
ΠΈ
l_whence
, ΠΈ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°. Бюда входят Ρ‚Π°ΠΊΠΆΠ΅ Π»ΡŽΠ±Ρ‹Π΅ области Π·Π° ΠΊΠΎΠ½Ρ†ΠΎΠΌ Ρ„Π°ΠΉΠ»Π°. (Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, Ссли Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» увСличиваСтся Π² Ρ€Π°Π·ΠΌΠ΅Ρ€Π΅, ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ΡΡ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ вСсь Ρ„Π°ΠΉΠ».) Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ всСго Ρ„Π°ΠΉΠ»Π° являСтся Π²Ρ‹Ρ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΌ случаСм блокирования ΠΎΠ΄Π½ΠΎΠΉ записи:

lock.l_whence = SEEK_SET; /* ΠΠ±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ */

lock.l_start = 0; /* Начало Ρ„Π°ΠΉΠ»Π° */

lock.l_len = 0; /* Π”ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π° */

Бправочная страница fnctl(3) ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

POSIX 1003.1-2001 допускаСт ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ значСния

l_len
. (И Ссли это Ρ‚Π°ΠΊ, описываСмый Π±Π»ΠΎΠΊΠΎΠΌ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π±Π°ΠΉΡ‚Ρ‹ с
l_start + l_len
Π²ΠΏΠ»ΠΎΡ‚ΡŒ Π΄ΠΎ
l_start - 1
Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ.) Однако, Π² этой ситуации систСмный Π²Ρ‹Π·ΠΎΠ² Linux для соврСмСнных ядСр Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚
EINVAL
.

(ΠœΡ‹ Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ справочная страница относится ΠΊ вСрсиям ядСр 2.4.x; стоит ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΡΠΏΡ€Π°Π²ΠΎΡ‡Π½ΡƒΡŽ страницу, Ссли ваша систСма Π½ΠΎΠ²Π΅Π΅.)

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ Π³Π΄Π΅ блокируСтся Ρ„Π°ΠΉΠ», ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚ΠΈΠΏ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ

l_type
. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ значСния ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅:

F_RDLCKΒ Β 
Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° чтСния. Для примСнСния Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ чтСния Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ для чтСния.

F_WRLCKΒ Β 
Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° записи. Для примСнСния Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записи Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ для записи.

F_UNLCKΒ Β 
ОсвобоТдСниС ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, полная спСцификация Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ установку Π² структурС

struct flock
Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… ΠΏΠΎΠ»Π΅ΠΉ: Ρ‚Ρ€Π΅Ρ… для указания Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ области ΠΈ Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠ³ΠΎ для описания Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° Π±Π»ΠΎΠΊΠ°.