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

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

Автор ОлСг Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ

Π’ Ρ‚Π°ΠΊΠΎΠΉ схСмС ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π² Ρ‚ΠΎΡ‡ΠΊΡƒ оТидания (ΠΈ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ Π΄Π΅Π»Π°ΡŽΡ‚ это) Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ своСго выполнСния. Π’ прСдставлСнном шаблонС ΠΌΡ‹ Π½Π΅ стали ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Π·Π°Π³Ρ€ΠΎΠΌΠΎΠΆΠ΄Π°Ρ‚ΡŒ ΠΊΠΎΠ΄. Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ рассматривался Ρ€Π°Π½Π΅Π΅, ΠΊΠΎΠ³Π΄Π° Ρ€Π΅Ρ‡ΡŒ шла ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

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

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

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

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

int pthread_barrierattr_setpshared(

pthread_barrierattr_t* attr, int pshared);

int pthread_barrierattr_getpshared(

const pthread_barrierattr_t* attr, int* pshared);

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ Π±Π°Ρ€ΡŒΠ΅Ρ€Π° Π·Π°ΠΏΡ€Π΅Ρ‰Π°ΡŽΡ‚ доступ ΠΊ элСмСнту синхронизации ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… процСссов.

ОбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ значСния:

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

EINVAL β€” ΠΎΠ΄Π½ΠΎ ΠΈΠ»ΠΈ ΠΎΠ±Π° ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π½Π΅Π²Π΅Ρ€Π½Ρ‹.

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΠΈ Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ Π±Π°Ρ€ΡŒΠ΅Ρ€Π°

int pthread_barrier_init(pthread_barrier_t* barrier,

 const pthread_barrierattr_t* attr, unsigned int count);

Ѐункция ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ синхронизации Ρ‚ΠΈΠΏΠ° Π±Π°Ρ€ΡŒΠ΅Ρ€, послС Ρ‡Π΅Π³ΠΎ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ. Π’ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°Ρ… Π±Π°Ρ€ΡŒΠ΅Ρ€Π° устанавливаСтся (ΠΈΠ»ΠΈ запрСщаСтся) Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ доступа ΠΊ Π±Π°Ρ€ΡŒΠ΅Ρ€Ρƒ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… процСссов. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ‚Π°ΠΊΠΎΠΉ доступ Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ доступа ΠΊ созданному Ρ€Π°Π½Π΅Π΅ Π±Π°Ρ€ΡŒΠ΅Ρ€Ρƒ, Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ€Π°Π·Ρ€ΡƒΡˆΠΈΡ‚ΡŒ, ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±Π°Ρ€ΡŒΠ΅Ρ€ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ count ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΎΠ΅ количСство ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅ Π΄ΠΎ ΠΈΡ… освобоТдСния.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния:

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

EAGAIN β€” систСмС Π½Π΅ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚ рСсурсов для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π±Π°Ρ€ΡŒΠ΅Ρ€Π°;

EBUSY β€” ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΡƒΠΆΠ΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π±Π°Ρ€ΡŒΠ΅Ρ€Π°;

EFAULT β€” сбой ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π» ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ядра ΠΊ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌ;

EINVAL β€” attr ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ².

int pthread_barrier_destroy(pthread_barrier_t* barrier);

Ѐункция Ρ€Π°Π·Ρ€ΡƒΡˆΠ°Π΅Ρ‚ Π±Π°Ρ€ΡŒΠ΅Ρ€, послС Ρ‡Π΅Π³ΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт синхронизации barrier Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π±Π΅Π· ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ Π΅Π³ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния:

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

EBUSY β€” Π² настоящСС врСмя Π΅ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅;

EINVAL β€” Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ barrier.

ОТиданиС Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅

Ѐункция оТидания (синхронизации) Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅:

int pthread_barrier_wait(pthread_barrier_t* barrier);

Π’Ρ‹Π·ΠΎΠ² этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅ Π½Π΅ накопится количСство Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_barrier_init().

НСобходимо с особой ΠΎΡΡ‚ΠΎΡ€ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚ΡŒΡΡ ΠΊ использованию Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠ² для остановки ΠΈ синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ². ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ Ρƒ Π±Π°Ρ€ΡŒΠ΅Ρ€Π°, находятся Π² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅ Π½Π° условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ (Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ), Ρ‚ΠΎ систСма Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ отслСТиваСт эффСкты, связанныС с Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ инвСрсиСй ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ².

Если ΠΏΠΎΡ‚ΠΎΠΊ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π½Π° Π±Π°Ρ€ΡŒΠ΅Ρ€Π΅, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ сигнал, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала выполняСтся, Π½ΠΎ ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Π΅Π³ΠΎ выполнСния ΠΏΠΎΡ‚ΠΎΠΊ вновь блокируСтся Π΄ΠΎ выполнСния условия Π±Π°Ρ€ΡŒΠ΅Ρ€Π°.

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