linux線程同步(5)-屏障

http://www.cnblogs.com/yuuyuu/p/5152560.html

一.概述 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

barrier(屏障)與互斥量,讀寫鎖,自旋鎖不同,它不是用來保護臨界區的。相反,它跟條件變量一樣,是用來協同多線程一起工作!!!

條件變量是多線程間傳遞狀態的改變來達到協同工作的效果。屏障是多線程各自做自己的工作,如果某一線程完成了工作,就等待在屏障那里,直到其他線程的工作都完成了,再一起做別的事。舉個通俗的例子:

1.對于條件變量。在接力賽跑里,1號隊員開始跑的時候,2,3,4號隊員都站著不動,直到1號隊員跑完一圈,把接力棒給2號隊員,2號隊員收到接力棒后就可以跑了,跑完再給3號隊員。這里這個接力棒就相當于條件變量,條件滿足后就可以由下一個隊員(線程)跑。

2.對于屏障。在百米賽跑里,比賽沒開始之前,每個運動員都在賽場上自由活動,有的熱身,有的喝水,有的跟教練談論。比賽快開始時,準備完畢的運動員就預備在起跑線上,如果有個運動員還沒準備完(除去特殊情況),他們就一直等,直到運動員都在起跑線上,裁判喊口號后再開始跑。這里的起跑線就是屏障,做完準備工作的運動員都等在起跑線,直到其他運動員也把準備工作做完!

二.函數接口 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

1.創建屏障

1 #include <pthread.h>
2 
3 int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count);

barrier:pthread_barrier_t結構體指針

attr:屏障屬性結構體指針

count:屏障等待的線程數目,即要count個線程都到達屏障時,屏障才解除,線程就可以繼續執行

2.等待

1 #include <pthread.h>
2 
3 int pthread_barrier_wait(pthread_barrier_t *barrier);

函數的成功返回值有2個,第一個成功返回的線程會返回PTHREAD_BARRIER_SERIAL_THREAD,其他線程都返回0。可以用第一個成功返回的線程來做一些善后處理工作。

3.銷毀屏障

1 #include <pthread.h>
2 
3 int pthread_barrier_destroy(pthread_barrier_t *barrier);

三.簡單例子 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

寫個簡單的例子,主線程等待其他線程都完成工作后自己再向下執行,類似pthread_join()函數!

復制代碼
 1 /**
 2  * @file pthread_barrier.c
 3  */
 4 
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 #include <string.h>
 8 #include <unistd.h>
 9 #include <pthread.h>
10 
11 /* 屏障總數 */
12 #define PTHREAD_BARRIER_SIZE 4
13 
14 /* 定義屏障 */
15 pthread_barrier_t barrier;
16 
17 void err_exit(const char *err_msg)
18 {
19     printf("error:%s\n", err_msg);
20     exit(1);
21 }
22 
23 void *thread_fun(void *arg)
24 {
25     int result;
26     char *thr_name = (char *)arg;
27 
28     /* something work */
29 
30     printf("線程%s工作完成...\n", thr_name);
31 
32     /* 等待屏障 */
33     result = pthread_barrier_wait(&barrier);
34     if (result == PTHREAD_BARRIER_SERIAL_THREAD)
35         printf("線程%s,wait后第一個返回\n", thr_name);
36     else if (result == 0)
37         printf("線程%s,wait后返回為0\n", thr_name);
38 
39     return NULL;
40 }
41 
42 int main(void)
43 {
44     pthread_t tid_1, tid_2, tid_3;
45 
46     /* 初始化屏障 */
47     pthread_barrier_init(&barrier, NULL, PTHREAD_BARRIER_SIZE);
48 
49     if (pthread_create(&tid_1, NULL, thread_fun, "1") != 0)
50         err_exit("create thread 1");
51 
52     if (pthread_create(&tid_2, NULL, thread_fun, "2") != 0)
53         err_exit("create thread 2");
54 
55     if (pthread_create(&tid_3, NULL, thread_fun, "3") != 0)
56         err_exit("create thread 3");
57 
58     /* 主線程等待工作完成 */
59     pthread_barrier_wait(&barrier);
60     printf("所有線程工作已完成...\n");
61 
62     sleep(1);
63     return 0;
64 }
復制代碼

28行是線程自己要做的工作,62行的sleep(1)讓所有線程有足夠的時間把自己的返回值打印出來。編譯運行:

可以看到,3個線程工作完成后才可以越過屏障打印返回值,第一個返回的是PTHREAD_BARRIER_SERIAL_THREAD,其他都是0。

這里有一點要注意:我們從運行結果看出,主線程打印"所有線程工作已完成"之后,線程1,線程2還在運行打印返回值。這個結果難免會誤解"主線程等待所有線程完成工作之后再向下執行"。區分一點即可:等待只針對屏障之前的動作,越過屏障后,無論是主線程,還是子線程都會并發執行,如果非要讓子線程完完全全執行完,可以再加個屏障到線程函數末尾,相應主線程也要加!


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384003.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384003.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384003.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

淺談軟件測試

一. 什么是軟件測試 軟件測試是一個過程或者一系列過程, 用來測試計算機代碼完成了其應該完成的功能, 不執行不該有的操作.或者說軟件測試是根據軟件開發各階段的功能和說明而精心設計的一批測試用例, 并根據測試用例運行程序, 以發現程序錯誤的過程. 二. 軟件測試的心理學和…

UVa10340

【題目描述】 傳送門 【題目分析】 求字串&#xff0c;最好還是處理母串&#xff0c;每次找到一個子串就加1&#xff0c;這樣處理不用處理細節 【AC代碼】 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include&l…

淺析linux下的條件變量

一.條件變量 條件變量是用來等待線程而不是上鎖的&#xff0c;條件變量通常和互斥鎖一起使用。條件變量之所以要和互斥鎖一起使用&#xff0c;主要是因為互斥鎖的一個明顯的特點就是它只有兩種狀態&#xff1a;鎖定和非鎖定&#xff0c;而條件變量可以通過允許線程阻塞和等待另…

UVa1587

【題目描述】 傳送門 【題目分析】 剛開始想簡單了&#xff0c;認為只要相對的面相等就可以了。然后發現三個不同方向的面的邊應該有相等的關系&#xff0c;即如果兩個面公用一條邊&#xff0c;那么這兩個面的另外兩條邊就是另一個面的兩條邊。而且這三個量里面肯定有一個最…

Linux多線程與同步

https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系統都支持一個進程創建多個線程(thread)。在Linux進程基礎中提到&#xff0c;Linux以進程為單位組織操作&#xff0c;Linux中的線程也都基于進程。盡管實現方式有異于其它的UNIX系統&#xff0c;但Linux的多線程…

內存管理(二)

頁面置換算法 當發生缺頁中斷的時候, 系統會在內存中選擇一個頁面將其換出內存, 而當換出內存的時候如果該頁面的內容在內存中發生修改,則必須將該新數據重新寫回到磁盤, 然后再將需要換進的數據覆蓋掉原來的數據, 而當該數據在內存中沒有被修改的時候, 此時就直接用需要換進的…

兩個棧實現一個隊列/兩個隊列實現一個棧

http://blog.csdn.net/sinat_30472685/article/details/70157227 1兩個棧實現一個隊列 1.原理分析&#xff1a; 隊列的主要操作有兩個&#xff1a;入隊操作和出隊操作&#xff0c;出隊時從隊頭出&#xff0c;入隊是從隊尾插入&#xff0c;入隊的操作和入棧的操作類似&#xff0…

UVa1588

【題目描述】 傳送門 【題目分析】 剛開始想了一會沒有想到什么很好的算法&#xff0c;看到了長度最多為100&#xff0c;就知道自己想的沒有什么意義了&#xff0c;直接暴力&#xff0c;把每一種填法都試一下就知道了。適當剪枝一下&#xff08;一個簡單的樂觀函數&#xff…

轉:C++中const、volatile、mutable的用法

const修飾普通變量和指針 const修飾變量&#xff0c;一般有兩種寫法&#xff1a; const TYPE value; TYPE const value; 這兩種寫法在本質上是一樣的。它的含義是&#xff1a;const修飾的類型為TYPE的變量value是不可變的。對于一個非指針的類型TYPE&#xff0c;無論怎么寫&…

數據鏈路

廣播信道的數據鏈路層 局域網的優點 網絡為一個單位所擁有, 地理范圍和站點數有限 局域網具有廣播特性, 可以從一個站點方便地訪問到整個網絡. 各個主機之間可以共享資源, 無論是局域網上的硬件資源還是局域網上的軟件資源 便于系統的擴展換和演化, 各個設備之間的位置可靈…

UVa11809

【題目描述】 傳送門 【題目分析】 終于把這道題做完了&#xff0c;之前一直連題意都看不懂。實在不行上網找了一下大佬的博客&#xff0c;看懂題意后自己寫&#xff0c;發現讀入很難處理&#xff0c;就又學習了一下大佬的讀入方法&#xff0c;用的是C里面的sstream&#xf…

數據鏈路層:基本概念

數據鏈路層的定義 對數據鏈路層有對上的網絡層接口. 對下提供物理層的接口. 定義合適的傳輸差錯率 對傳輸流進行管理, 以免快速的傳輸的數據被淹沒. 比如發送端發送信號太快, 接受方接受速度較慢, 此時數據鏈路層就需要提供一定的功能解決這個問題 物理層上傳輸的基本單元是…

C++的沉迷與愛戀

每年的 09/28 於我都是一個特殊的日子 -- 不只是因為教師節。今年很特殊地沒有普天同慶&#xff0c;那麼我就寫篇文章自己慶祝一下好了。我於今年七月發表了一本著作《多型與虛擬》和一本譯作《深度探索C物件模型》&#xff0c;獲得很大的回響。這些作品都不是針對 C 的完全初學…

Insertion Sort——打表找規律

【題目描述】 Insertion sort is a simple sorting algorithm that builds the final sorted array one item at an iteration.More precisely, insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. At each iteration…

數據鏈路層: 可靠性傳輸 六個協議

可靠性傳輸 1. 差錯控制 發送方將數據幀發送, 但是當發送方發送的是一個 1的時候此時接受方卻接受的是一個 0. (1)校驗 接收方如果幀校驗接受到的幀沒有問題, 則對發送方發送一個肯定性的確認, 當對這個數據幀進行校驗發現這個幀有問題的時候, 此時接受方一種是將這個數據幀…

c語言實現配置文件的讀寫

配置文件的格式如下&#xff1a; key1 value1 key2 value2 . . . 名值對以一個鏈接&#xff0c;一條記錄以換行符分割 頭文件&#xff1a; #include<stdio.h> #include<stdlib.h> #include <string.h> 函數原型&#xff1a; void trim(char *strIn, char *…

Educational Codeforces Round 73 (Rated for Div. 2)

A 很簡單的一個模擬&#xff0c;只要前面的數字有兩個以上就能合成后面的&#xff0c;我們進行一遍合成看能不能出現2048就可以了。 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include&…

數據鏈路層: HDLC

一. 協議機 發送方和接收方. 同時有限狀態機把協議形式化為一個四元組 (S,M,I,T), 其中你S表示進程和信道可能進入的集合, M 表示數據幀的狀態, I 表示進程的初始狀態, T 表示兩兩狀態之間的轉化. 每個系統狀態可以分為發送狀態, 接受狀態和信道狀態. 把狀態用一個點進行表示,…

Miller_Rabin算法

為了測試一個大整數是不是素數&#xff0c;我們不能夠使用傳統的測試是否有因子的方法&#xff0c;因為那樣的時間復雜度至少也是O(n)O(n)O(n)&#xff0c;空間復雜度是O(n)O(n)O(n)&#xff08;使用線性篩數法&#xff09;&#xff0c;時間復雜度還好說&#xff0c;空間復雜度…

bob-tong 字符串函數之Strtok()函數

https://www.cnblogs.com/Bob-tong/p/6610806.html Strtok()函數詳解&#xff1a; 該函數包含在"string.h"頭文件中 函數原型&#xff1a; char* strtok (char* str,constchar* delimiters ); 函數功能&#xff1a; ??切割字符串&#xff0c;將str切分成一個個子…