LIBUV学习笔记 uv_barrier_xxx与pthread_barrier_xxx相关

Posted J1ac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LIBUV学习笔记 uv_barrier_xxx与pthread_barrier_xxx相关相关的知识,希望对你有一定的参考价值。

在学习libuv的线程相关API的时候碰到了uv_barrier_xxx相关函数,虽然说libuv的线程库总的来说和pthread差不多,但在看APUE的时候都没碰到过线程同步相关里面这个概念,于是网上查找了一下,总结如下:

pthread_barrier_xxx系列函数在<pthread.h>中定义,用于多线程的同步,它包含下列三个函数:

     1. pthread_barrier_init();

     2. pthread_barrier_wait();

     3. pthread_barrier_destroy();

      pthread_barrier_xxx其实只做且只能做一件事,就是充当栏杆(barrier意为栏杆)形象的说就是把先后到达的多个线程挡在同一栏杆前,直到所有线程到齐,然后撤下栏杆同时放行。

      1)、init函数负责指定要等待的线程个数;

      2)、wait()函数由每个线程主动调用,它告诉栏杆“我到起跑线前了”。wait()执行末尾栏杆会检查是否所有人都到栏杆前了,如果是,栏杆就消失所有线程继续执行下一句代码;如果不是,则所有已到wait()的线程停在该函数不动,剩下没执行到wait()的线程继续执行;

      3)、destroy函数释放init申请的资源。

 

1、函数原型

#include <pthread.h>

int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count);

int pthread_barrier_wait(pthread_barrier_t *barrier);

int pthread_barrier_destroy(pthread_barrier_t *barrier);

参数解释:

pthread_barrier_t:是一个计数锁,对该锁的操作都包含在三个函数内部,我们不用关心也无法直接操作,只需要实例化一个对象丢给它就好。

pthread_barrierattr_t:锁的属性设置,设为NULL让函数使用默认属性即可。

count:你要指定的等待个数。

2、使用场景

      这种“栏杆”机制最大的特点就是最后一个执行wait的动作最为重要,就像赛跑时的起跑枪一样,它来之前所有人都必须等着。所以实际使用中,pthread_barrier_xxx常常用来让所有线程等待“起跑枪”响起后再一起行动。比如我们可以用pthread_create()生成100个线程,每个子线程在被create出的瞬间就会自顾自的立刻进入回调函数运行。但我们可能不希望它们这样做,因为这时主进程还没准备好,和它们一起配合的其它线程还没准备好,我们希望它们在回调函数中申请完线程空间、初始化后停下来,一起等待主进程释放一个“开始”信号,然后所有线程再开始执行业务逻辑代码。

      为了解决上述场景问题,我们可以在init时指定n+1个等待,其中n是线程数。而在每个线程执行函数的首部调用wait()。这样100个pthread_create()结束后所有线程都停下来等待最后一个wait()函数被调用。这个wait()由主进程在它觉得合适的时候调用就好。最后这个wait()就是鸣响的起跑枪。

3、LIBUV相关函数

  三个相关函数原型:

  int uv_barrier_init(uv_barrier_t* barrier, unsigned int count)
  void uv_barrier_destroy(uv_barrier_t* barrier)
  int uv_barrier_wait(uv_barrier_t* barrier)

使用方法和pthread一样,下面用LIBUV里面的一个例子解释一下:

 1 #include <stdio.h>
 2 #include <uv.h>
 3 
 4 uv_barrier_t blocker;
 5 uv_rwlock_t numlock;
 6 int shared_num;
 7 
 8 void reader(void *n)
 9 {
10     int num = *(int *)n;
11     int i;
12     for (i = 0; i < 20; i++) {
13         uv_rwlock_rdlock(&numlock);//读锁
14         printf("Reader %d: acquired lock\n", num);
15         printf("Reader %d: shared num = %d\n", num, shared_num);
16         uv_rwlock_rdunlock(&numlock);
17         printf("Reader %d: released lock\n", num);
18     }
19     uv_barrier_wait(&blocker);
20 }
21 
22 void writer(void *n)
23 {
24     int num = *(int *)n;
25     int i;
26     for (i = 0; i < 20; i++) {
27         uv_rwlock_wrlock(&numlock);//写锁
28         printf("Writer %d: acquired lock\n", num);
29         shared_num++;
30         printf("Writer %d: incremented shared num = %d\n", num, shared_num);
31         uv_rwlock_wrunlock(&numlock);
32         printf("Writer %d: released lock\n", num);
33     }
34     uv_barrier_wait(&blocker);
35 }
36 
37 int main()
38 {
39     uv_barrier_init(&blocker, 4);
40 
41     shared_num = 0;
42     uv_rwlock_init(&numlock);
43 
44     uv_thread_t threads[3];
45 
46     int thread_nums[] = {1, 2, 1};
47     uv_thread_create(&threads[0], reader, &thread_nums[0]);
48     uv_thread_create(&threads[1], reader, &thread_nums[1]);
49 
50     uv_thread_create(&threads[2], writer, &thread_nums[2]);
51 
52     uv_barrier_wait(&blocker);//等待子线程全部调用uv_barrier_wait
53     uv_barrier_destroy(&blocker);
54 
55     uv_rwlock_destroy(&numlock);
56     return 0;
57 }

一个可能的输出:

Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 1: acquired lock
Reader 1: shared num = 0
Reader 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 0
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 1
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 2
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 3
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 4
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 5
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 6
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 7
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 8
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 9
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 10
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 11
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 12
Writer 1: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 13
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 13
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 13
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 13
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 13
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 13
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 14
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 14
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 15
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 15
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 16
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 16
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 17
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 17
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 18
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 18
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 19
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 19
Reader 2: released lock
Writer 1: acquired lock
Writer 1: incremented shared num = 20
Writer 1: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock
Reader 2: acquired lock
Reader 2: shared num = 20
Reader 2: released lock

 参考:https://blog.csdn.net/jackailson/article/details/51052609

以上是关于LIBUV学习笔记 uv_barrier_xxx与pthread_barrier_xxx相关的主要内容,如果未能解决你的问题,请参考以下文章

libuv学习笔记

lua+libuv的一些开发心得

lua+libuv的一些开发心得

lua+libuv的一些开发心得

从libuv源码学习线程池

从libuv源码学习线程池