[pthread] 同步机制(4) ---- barrier (REALTIME)
2010-01-06 21:36:33| 分类:
pthread
| 标签:
|举报
|字号大中小 订阅
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 one
pthread_cond_wait(&impl->cond, &impl->m);
pthread_mutex_unlock(&impl->m);
return 0;
}
-------------------------------
评论这张
转发至微博
转发至微博
评论