Linux编程-pthread_barrier_xxx介绍
 2016.04.03    |      应用编程    |     AilsonJack    |     暂无评论    |     1400 views
By: Ailson Jack
Date: 2016-04-03
个人博客: http://www.only2fire.com/
<p style="text-indent: 2em;">pthread_barrier_xxx系列函数在&lt;pthread.h&gt;中定义,用于多线程的同步,它包含下列三个函数:<br/></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">—pthread_barrier_init();<br/></span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">—pthread_barrier_wait();<br/></span></p><p style="text-indent: 2em;"><span style="color: rgb(0, 112, 192);">—pthread_barrier_destroy();</span><br/></p><p style="text-indent: 2em;">那么pthread_barrier_xxx是用来做什么的?这三个函数又怎么配合使用呢?<br/></p><p style="text-indent: 2em;">pthread_barrier_xxx其实只做且只能做一件事,就是充当栏杆(barrier意为栏杆)形象的说就是把先后到达的多个线程挡在同一栏杆前,直到所有线程到齐,然后撤下栏杆同时放行。<br/></p><p style="text-indent: 2em;"><span style="background-color: rgb(118, 146, 60);">1)、</span>init函数负责指定要等待的线程个数;<br/></p><p style="text-indent: 2em;"><span style="background-color: rgb(118, 146, 60);">2)、</span>wait()函数由每个线程主动调用,它告诉栏杆“我到起跑线前了”。wait()执行末尾栏杆会检查是否所有人都到栏杆前了,如果是,栏杆就消失所有线程继续执行下一句代码;如果不是,则所有已到wait()的线程停在该函数不动,剩下没执行到wait()的线程继续执行;<br/></p><p style="text-indent: 2em;"><span style="background-color: rgb(118, 146, 60);">3)、</span>destroy函数释放init申请的资源。</p><p class="artical_littlestyle1">1、函数原型</p><p style="text-indent: 0em;"><span style="color: rgb(0, 112, 192);">#include &lt;pthread.h&gt;<br/>int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count);<br/>int pthread_barrier_wait(pthread_barrier_t *barrier);<br/>int pthread_barrier_destroy(pthread_barrier_t *barrier);</span><br/></p><p style="text-indent: 2em;">参数解释:<br/><span style="color: rgb(0, 112, 192);">pthread_barrier_t</span>:是一个计数锁,对该锁的操作都包含在三个函数内部,我们不用关心也无法直接操作,只需要实例化一个对象丢给它就好。<br/><span style="color: rgb(0, 112, 192);">pthread_barrierattr_t</span>:锁的属性设置,设为NULL让函数使用默认属性即可。<br/><span style="color: rgb(0, 112, 192);">count</span>:你要指定的等待个数。</p><p class="artical_littlestyle2">2、使用场景</p><p style="text-indent: 2em;">这种“栏杆”机制最大的特点就是最后一个执行wait的动作最为重要,就像赛跑时的起跑枪一样,它来之前所有人都必须等着。所以实际使用中,pthread_barrier_xxx常常用来让所有线程等待“起跑枪”响起后再一起行动。比如我们可以用pthread_create()生成100个线程,每个子线程在被create出的瞬间就会自顾自的立刻进入回调函数运行。但我们可能不希望它们这样做,因为这时主进程还没准备好,和它们一起配合的其它线程还没准备好,我们希望它们在回调函数中申请完线程空间、初始化后停下来,一起等待主进程释放一个“开始”信号,然后所有线程再开始执行业务逻辑代码。<br/></p><p style="text-indent: 2em;">为了解决上述场景问题,我们可以在init时指定n+1个等待,其中n是线程数。而在每个线程执行函数的首部调用wait()。这样100个pthread_create()结束后所有线程都停下来等待最后一个wait()函数被调用。这个wait()由主进程在它觉得合适的时候调用就好。最后这个wait()就是鸣响的起跑枪。</p><p class="artical_littlestyle3">3、程序示例</p><p style="text-indent: 2em;">下面的程序,在main函数中,<span style="color: rgb(0, 112, 192);">pthread_barrier_init()</span>指定2+1个等待,接着创建了2个线程,然后主进程延时6秒,之后调用<span style="color: rgb(0, 112, 192);">pthread_barrier_wait()</span>来让线程接着运行,程序如下:</p><pre class="brush:cpp;toolbar:false PrismJs">/* ******************************************************************************** *描述:pthread_barrier_xxx程序示例 *Use:gcc&nbsp;pthread_barrier_xxx.c&nbsp;-lpthread *&nbsp;&nbsp;&nbsp;&nbsp;./a.out *By:Ailson&nbsp;Jack *Date:2016.03.24 *Blog:www.only2fire.com ******************************************************************************** */ #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;stdio.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;unistd.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;pthread.h&gt; #include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;time.h&gt; pthread_barrier_t&nbsp;barrier; void&nbsp;*Task1(void&nbsp;*arg); void&nbsp;*Task2(void&nbsp;*arg); int&nbsp;main(void) { &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;policy,inher; &nbsp;&nbsp;&nbsp;&nbsp;pthread_t&nbsp;tid; &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_t&nbsp;attr; &nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;sched_param&nbsp;param; &nbsp;&nbsp;&nbsp;&nbsp;//初始化线程属性 &nbsp;&nbsp;&nbsp;&nbsp;pthread_attr_init(&amp;attr); &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_init(&amp;barrier,NULL,2&nbsp;+&nbsp;1);//2+1个等待 &nbsp;&nbsp;&nbsp;&nbsp;//创建线程1 &nbsp;&nbsp;&nbsp;&nbsp;pthread_create(&amp;tid,&nbsp;&amp;attr,Task1,NULL); &nbsp;&nbsp;&nbsp;&nbsp;//创建线程2 &nbsp;&nbsp;&nbsp;&nbsp;pthread_create(&amp;tid,&nbsp;&amp;attr,Task2,NULL); &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;main&nbsp;process&nbsp;will&nbsp;sleep&nbsp;6s.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;sleep(6);/*等待6s后,才让线程运行*/ &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_wait(&amp;barrier);//起跑枪“砰!” &nbsp;&nbsp;&nbsp;&nbsp;pthread_join(tid,&nbsp;NULL); &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_destroy(&amp;barrier); } void&nbsp;*Task1(void&nbsp;*arg) { &nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Task1&nbsp;will&nbsp;be&nbsp;blocked.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_wait(&amp;barrier);//所有线程都被阻塞在这里 &nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Task1&nbsp;is&nbsp;running.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;sleep(3);//延时3s &nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL); } void&nbsp;*Task2(void&nbsp;*arg) { &nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Task2&nbsp;will&nbsp;be&nbsp;blocked.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;pthread_barrier_wait(&amp;barrier);//所有线程都被阻塞在这里 &nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Task2&nbsp;is&nbsp;running.\r\n&quot;); &nbsp;&nbsp;&nbsp;&nbsp;sleep(3);//延时3s &nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL); }</pre><p style="text-indent: 2em;">程序的运行结果如下图所示:</p><p style="text-align: center;"><img src="/uploads/AilsonJack/2018.08.25/1535207799161323.png" onclick="preview_image(&#39;/uploads/AilsonJack/2018.08.25/1535207799161323.png&#39;)"/></p>
欢迎关注博主的公众号呀,精彩内容随时掌握:
热情邀请仔细浏览下博客中的广告,万一有对自己有用或感兴趣的呢。◕ᴗ◕。。
如果这篇文章对你有帮助,记得点赞和关注博主就行了^_^,当然了能够赞赏博主,那就非常感谢啦!
注: 转载请注明出处,谢谢!^_^
转载请注明来源: 本文链接:  By: AilsonJack
Linux编程-pthread_barrier_xxx介绍  |  说好一起走
暂无评论,要不要来个沙发
发表评论

 
Copyright © 2015~2023  说好一起走   保留所有权利   |  百度统计  蜀ICP备15004292号