使用场景 这种“栏杆”机制最大的特点就是最后一个执行wait的动作最为重要, pthread_barrier_xxx让所有线程等待,所有线程准备好后再一起行动。 如pthread_create()生成100个线程,每个子线程在被create出的瞬间就会自顾自的立刻进入回调函数运行。 但我们可能不希望它们这样做,因为这时主进程还没准备好,和它们一起配合的其它线程还没准备好,我们希望它们在回调函数中申请完线程空间、初始化后停下来, 一起等待主进程释放一个“开始”信号,然后所有线程再开始执行业务逻辑代码。
/* 函数名:uv_barrier_init 参 数:uv_barrier_t* barrier -- barrier指针 参 数:unsigned int count -- 线程数量 说 明:初始化barrier指针,等待同步count个线程。 */ int uv_barrier_init(uv_barrier_t* barrier, unsigned int count); /* 函数名:uv_barrier_wait 参 数:uv_barrier_t* barrier -- barrier指针 说 明:等待n个线程全部执行完成,才往下执行 */ int uv_barrier_wait(uv_barrier_t* barrier); /* 函数名:uv_barrier_destroy 参 数:uv_barrier_t* barrier -- barrier指针 说 明:释放barrier资源 */ void uv_barrier_destroy(uv_barrier_t* barrier);
#include <cstdio> #include <stdio.h> #include <stdlib.h> #include <libuv/uv.h> //同步栏杆 uv_barrier_t blocker; //读写锁 uv_rwlock_t numlock; //共享变量 int shared_num; void reader(void* n) { int num = *(int*)n; int i; for (i = 0; i < 5; i++) { //读锁 uv_rwlock_rdlock(&numlock); printf("Reader %d: acquired lock\n", num); printf("Reader %d: shared num = %d\n", num, shared_num); uv_rwlock_rdunlock(&numlock); printf("Reader %d: released lock\n", num); } //线程需要等待其他一些线程任务完成之后,才能继续运行时 uv_barrier_wait(&blocker); } void writer(void* n) { int num = *(int*)n; int i; for (i = 0; i < 5; i++) { //写锁 uv_rwlock_wrlock(&numlock); printf("Writer %d: acquired lock\n", num); shared_num++; printf("Writer %d: incremented shared num = %d\n", num, shared_num); uv_rwlock_wrunlock(&numlock); printf("Writer %d: released lock\n", num); } //线程需要等待其他一些线程任务完成之后,才能继续运行时 uv_barrier_wait(&blocker); } int main() { //初始化要同步的线程个数n + 1 uv_barrier_init(&blocker, 4); shared_num = 0; uv_rwlock_init(&numlock); uv_thread_t threads[3]; int thread_nums[] = { 1, 2, 3 }; uv_thread_create(&threads[0], reader, &thread_nums[0]); uv_thread_create(&threads[1], reader, &thread_nums[1]); uv_thread_create(&threads[2], writer, &thread_nums[2]); //线程需要等待其他一些线程任务完成之后,才能继续运行时 uv_barrier_wait(&blocker); uv_barrier_destroy(&blocker); uv_rwlock_destroy(&numlock); return 0; }