ΠΠΎΠΊΠ°Π·Π°Π½Π½Π°Ρ ΡΡ Π΅ΠΌΠ° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ Π½Π° Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠΌ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΈ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΊΠΎΠ²ΡΡ , Π½ΠΎ ΠΎΠ½Π° Π²ΡΠ²ΠΎΠ΄ΠΈΡ Π½Π°Ρ Π½Π° Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΡΠΈΠΏ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ²Β β Π±Π°ΡΡΠ΅Ρ.
ΠΠ°ΡΡΠ΅Ρ
ΠΠ°ΡΡΠ΅Ρ ΠΊΠ°ΠΊ ΡΠ°Π· ΠΈ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ Π΄Π»Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ Π²ΡΡΠ΅ ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ΅Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ β ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΡΡΠ»ΠΎΠ²ΠΈΡ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π·Π°Π΄Π°Π½Π½ΡΠΌΠΈ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ ΡΠΎΡΠΊΠΈ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠΎΡΡΠΈΠ³Π½ΡΠ² ΡΡΠΎΠΉ ΡΠΎΡΠΊΠΈ, ΠΏΠΎΡΠΎΠΊΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡΡΡΡ Β«ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΒ» ΠΈ ΡΠΆΠ΅ Ρ ΡΡΠΎΠΉ ΡΠΎΡΠΊΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ ΡΠ²ΠΎΠ΅ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎΠ΅ ΡΠ°Π·Π²ΠΈΡΠΈΠ΅. Β«ΠΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠ°ΡΒ» ΡΡ Π΅ΠΌΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π±Π°ΡΡΠ΅ΡΠ° (ΠΈΠΌΠ΅Π½Π½ΠΎ Π² ΡΠ°ΠΊΠΎΠΌ ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΎΠ½ ΡΠ°ΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ), Π½Π΅ΠΎΠ΄Π½ΠΎΠΊΡΠ°ΡΠ½ΠΎ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠΌΠ°Ρ Π² ΠΎΠΏΠΈΡΠ°Π½ΠΈΡΡ , Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ (ΠΌΡ ΡΠΆΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ°Π· ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ Π΅Π΅ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ ΠΊΠΎΠ΄Π°):
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
EINVALattrΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π±Π°ΡΡΠ΅ΡΠ° ΠΎΠΏΠΈΡΡΠ²Π°ΡΡΡΡ ΡΠΈΠΏΠΎΠΌ
pthread_barrierattr_t