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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QNX/UNIX: Анатомия ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ°Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 73

Автор Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ ОлСг Π˜Π²Π°Π½ΠΎΠ²ΠΈΡ‡

Показанная схСма синхронизации Π½Π° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π½Π΅ являСтся ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠΌ синхронизации ΠΈ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ использования Ρ‚Π°ΠΊΠΎΠ²Ρ‹Ρ…, Π½ΠΎ ΠΎΠ½Π° Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ нас Π½Π° Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ Ρ‚ΠΈΠΏ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ²Β β€” Π±Π°Ρ€ΡŒΠ΅Ρ€.

Π‘Π°Ρ€ΡŒΠ΅Ρ€

Π‘Π°Ρ€ΡŒΠ΅Ρ€ ΠΊΠ°ΠΊ Ρ€Π°Π· ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π²Ρ‹ΡˆΠ΅ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ β€” оТидания условия достиТСния нСсколькими Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ Ρ‚ΠΎΡ‡ΠΊΠΈ синхронизации. Достигнув этой Ρ‚ΠΎΡ‡ΠΊΠΈ, ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ΡΡ Β«ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΒ» ΠΈ ΡƒΠΆΠ΅ с этой Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽΡ‚ своС нСзависимоС Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅. Β«ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠ°ΡΒ» схСма использования Π±Π°Ρ€ΡŒΠ΅Ρ€Π° (ΠΈΠΌΠ΅Π½Π½ΠΎ Π² Ρ‚Π°ΠΊΠΎΠΌ качСствС ΠΎΠ½ Ρ‡Π°Ρ‰Π΅ всСго ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ), Π½Π΅ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ приводимая Π² описаниях, выглядит Ρ‚Π°ΠΊ (ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π· использовали Π΅Π΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… ΠΊΠΎΠ΄Π°):

static pthread_barrier_t bfinish;

void* threadfunc(void* data) {

Β // ΠΏΠΎΡ‚ΠΎΠΊΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π΄Π΅Π»Π°ΡŽΡ‚ ...

Β pthread_barrier_wait(&bfinish);

Β return NULL;

}

int main(int argc, char *argv[]) {

Β int N = ...; // Π±ΡƒΠ΄Π΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ N ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Β if (pthread_barrier_init(&bfinish, NULL, N + 1) != EOK)

Β  perror("barrier init"), exit(EXIT.FAILURE);

Β for (int i = 0; i < N; i++)

Β  if (pthread_create(NULL, NULL, threadfunc, NULL) != EOK)

Β Β  perror("thread create"), exit(EXIT_FAILURE);

Β pthread_barrier_wait(&bfinish);

}

ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ эта схСма ΠΌΠ°Π»ΠΎ отличаСтся ΠΎΡ‚ оТидания Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π½Π°

pthread_join()
, описанного Π²Ρ‹ΡˆΠ΅. Однако Π΅ΡΡ‚ΡŒ различия Π² ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ: Ссли Ρ€Π°Π½Π΅Π΅ ΠΌΡ‹ просто ΠΎΠΆΠΈΠ΄Π°Π»ΠΈ ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΉ схСмС ΠΌΡ‹ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ достиТСния ΠΈΠΌΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ созданной Ρ‚ΠΎΡ‡ΠΊΠΈ синхронизации. Π•Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ схСма синхронизации с ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π½Π°
pthread_join()
ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для «присоСдинСнных» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ схСма Π½Π°
pthread_barrier_wait()
ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ ΠΈ ΠΊ «отсоСдинСнным», Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ.

Но Ссли Π±Ρ‹ Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ Π΄Π²ΡƒΡ… схСм Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° Ρ‚ΠΎΠΌ ΠΈ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π»ΠΎΡΡŒ, Ρ‚ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, нСцСлСсообразно Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π²Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠ². Однако Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ° использования Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠ² ΡˆΠΈΡ€Π΅, ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹, Π½Π°ΠΏΡ€ΠΎΡ‚ΠΈΠ², ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ создаваСмыС ΠΏΠΎΡ‚ΠΎΠΊΠΈ (Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°) стартовали Π½Π° исполнСниС Β«ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΒ» (особСнно это Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½ΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ с Π±ΠΎΠ»Π΅Π΅ высоким ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠΌ, Ρ‡Π΅ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΉ):

static pthread_barrier_t bstart;

void* threadfunc(void* data) {

Β // всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ послС создания Π΄ΠΎΠ»ΠΆΠ½Ρ‹ "Π·Π°ΡΡ‚Ρ€ΡΡ‚ΡŒ" Π½Π° Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅,

Β // Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ‚ΠΎΠΌ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ "ΡΠΎΡ€Π²Π°Ρ‚ΡŒΡΡ" Π² исполнСниС...

Β pthread_barrier_wait(&bstart);

Β // ... Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ...

Β return NULL;

}

int main(int argc, char *argv[]) {

Β ...

Β int N = ...; // Π±ΡƒΠ΄Π΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ N ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Β if (pthread_barrier_init(&bstart, NULL, N) != EOK)

Β  perror("barrier init"), exit(EXIT_FAILURE);

Β for (int i = 0; i < nthr; i++) {

Β  if (pthread_create(NULL, NULL, threadfunc, NULL) != EOK)

Β  perror("thread create"), exit(EXIT_FAILURE);

Β }

Β ...

}

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ количСства ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΡ€ΠΈ Π΅Π³ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ: здСсь ΠΎΠ½ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ мСньшС.

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠ² ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описано Π² Π»ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΡƒΡ€Π΅ [1], поэтому ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° этом элСмСнтС синхронизации, Ρ‚Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅ Ρ‡Ρ‚ΠΎ это ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ простых Π² ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ элСмСнтов.

По нСпонятным ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ докумСнтация QNX [8] причисляСт Π±Π°Ρ€ΡŒΠ΅Ρ€Ρ‹ ΠΊ элСмСнтам синхронизации ядра, ΠΎΠ΄Π½Π°ΠΊΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… срСдств native API QNX, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π±Π°Ρ€ΡŒΠ΅Ρ€Π°ΠΌΠΈ, докумСнтация Π½Π΅ описываСт, Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»

<pthread.h>
Ρ‚Π°ΠΊ описываСт Ρ‚ΠΈΠΏ
pthread_barrier_t
:

typedef struct {

Β unsigned int barrier;

Β unsigned int count;

Β pthread_mutex_t lock;

Β pthread_cond_t bcond;

} pthread_barrier_t;

Π’Ρ‹Π²ΠΎΠ΄Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ.

Π’Π°ΠΊΠΆΠ΅ нСсколько Π·Π°Π³Π°Π΄ΠΎΡ‡Π½ΠΎ выглядит Ρ‚ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ согласно Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ QNX 6.2.1 всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠΌ ΠΈ Π΅Π³ΠΎ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ описаны Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅

<pthread.h>
, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π΄Π²ΡƒΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ
pthread_barrier_wait()
ΠΈ
pthread_barrierattr_setpshared()
, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… говорится, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ описаны Π² Ρ„Π°ΠΉΠ»Π΅
<sync.h>
! Но Ссли Π·Π°Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹, Ρ‚ΠΎ выясняСтся, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ спокойно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ всСх Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠΌ Π»ΠΈΠ±ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»
<pthread.h>
, Π»ΠΈΠ±ΠΎ
<sync.h>
.

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с Π±Π°Ρ€ΡŒΠ΅Ρ€Π°ΠΌΠΈ

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π±Π°Ρ€ΡŒΠ΅Ρ€Π°

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ ΠΈ Ρ€Π°Π·Ρ€ΡƒΡˆΠ°ΡŽΡ‚ Π±Π»ΠΎΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π±Π°Ρ€ΡŒΠ΅Ρ€Π°:

int pthread_barrierattr_init(pthread_barrierattr_t* attr);

int pthread_barrierattr_destroy(pthread_barrierattr_t* attr);

Ѐункция ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ значСния:

EOK
β€” ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅;

ENOMEM
β€” нСдостаточно памяти для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² Π±Π°Ρ€ΡŒΠ΅Ρ€Π°.

Ѐункция Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ значСния:

EOK
β€” ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅;

EINVAL
β€” ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² Π±Π°Ρ€ΡŒΠ΅Ρ€Π°
attr
.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π±Π°Ρ€ΡŒΠ΅Ρ€Π° ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Ρ‚ΠΈΠΏΠΎΠΌ

pthread_barrierattr_t
ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ‚ΠΈΠΏΠ°ΠΌ синхронизации ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ элСмСнта синхронизации. ЀактичСски СдинствСнным Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ Π±Π°Ρ€ΡŒΠ΅Ρ€Π° являСтся ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ доступа ΠΊ Π±Π°Ρ€ΡŒΠ΅Ρ€Ρƒ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… процСссов: