barrier (栅栏),就是等待 N 个线程都到达了某一阶段后,同时唤醒。N 可以由 pthread_barrier_init 设置。被唤醒的所有线程中,有一个 pthread_barrier_wait 返回值为 PTHREAD_BARRIER_SERIAL_THREAD,其它为 0。 barrier 有个 process-shared 的属性,意义不大,忽略。 -------------------------------- #include <stdio.h> #include <time.h> #include <unistd.h> #include <pthread.h> pthread_barrier_t global_barrier; void *mythr(void *arg) { int n = (int)arg; printf("thr #%d, enter, time = %d\n", n, time(NULL)); sleep(n); if ( pthread_barrier_wait(&global_barrier) == PTHREAD_BARRIER_SERIAL_THREAD ) printf("thr #%d, SERIAL_THREAD, leave, time = %d\n", n, time(NULL)); else printf("thr #%d, leave, time = %d\n", n, time(NULL)); return (void *)0; } int main() { pthread_t pid1, pid2, pid3; pthread_barrier_init(&global_barrier, NULL, 3); pthread_create(&pid1, NULL, mythr, (void *)1); pthread_create(&pid2, NULL, mythr, (void *)3); pthread_create(&pid3, NULL, mythr, (void *)5); pthread_join(pid1, NULL); pthread_join(pid2, NULL); pthread_join(pid3, NULL); return 0; } -------------------------------- $ ./a.out thr #3, enter, time = 1262784886 thr #5, enter, time = 1262784886 thr #1, enter, time = 1262784886 thr #5, SERIAL_THREAD, leave, time = 1262784891 thr #1, leave, time = 1262784891 thr #3, leave, time = 1262784891 -------------------------------- barrier 的实现 barrier 的功能很简单,自己可通过 mutex, cond 手工打造一个: ------------------------------- /* kbarrier.h */ #ifndef KCODE_KBARRIER_H #define KCODE_KBARRIER_H #include <pthread.h> #define KBARRIER_SERIAL_THREAD -1 struct kbarrier; typedef struct kbarrier *kbarrier_t; int kbarrier_init(kbarrier_t *b, unsigned int cnt); int kbarrier_destoy(kbarrier_t *b); int kbarrier_wait(kbarrier_t *b); #endif ------------------------------- /* kbarrier.c */ #include <stdlib.h> #include "kbarrier.h" struct kbarrier { pthread_mutex_t m; pthread_cond_t cond; unsigned int cnt; }; int kbarrier_init(kbarrier_t *b, unsigned int cnt) { kbarrier_t impl = (kbarrier_t) malloc(sizeof(struct kbarrier)); pthread_mutex_init(&impl->m, NULL); pthread_cond_init(&impl->cond, NULL); impl->cnt = cnt; *b = impl; return 0; } int kbarrier_destoy(kbarrier_t *b) { pthread_mutex_destroy(&(*b)->m); pthread_cond_destroy(&(*b)->cond); free(*b); return 0; } int kbarrier_wait(kbarrier_t *b) { kbarrier_t impl = *b; pthread_mutex_lock(&impl->m); impl->cnt--; if ( impl->cnt == 0 ) { // last thread pthread_mutex_unlock(&impl->m); pthread_cond_broadcast(&impl->cond); return KBARRIER_SERIAL_THREAD; } // not the last on pthread_cond_wait(&impl->cond, &impl->m); pthread_mutex_unlock(&impl->m); return 0; } ------------------------------- |
|
来自: astrotycoon > 《thread》