日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux线程同步(5)-屏障

發(fā)布時(shí)間:2025/3/21 linux 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux线程同步(5)-屏障 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

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

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

1.對(duì)于條件變量。在接力賽跑里,1號(hào)隊(duì)員開(kāi)始跑的時(shí)候,2,3,4號(hào)隊(duì)員都站著不動(dòng),直到1號(hào)隊(duì)員跑完一圈,把接力棒給2號(hào)隊(duì)員,2號(hào)隊(duì)員收到接力棒后就可以跑了,跑完再給3號(hào)隊(duì)員。這里這個(gè)接力棒就相當(dāng)于條件變量,條件滿足后就可以由下一個(gè)隊(duì)員(線程)跑。

2.對(duì)于屏障。在百米賽跑里,比賽沒(méi)開(kāi)始之前,每個(gè)運(yùn)動(dòng)員都在賽場(chǎng)上自由活動(dòng),有的熱身,有的喝水,有的跟教練談?wù)摗1荣惪扉_(kāi)始時(shí),準(zhǔn)備完畢的運(yùn)動(dòng)員就預(yù)備在起跑線上,如果有個(gè)運(yùn)動(dòng)員還沒(méi)準(zhǔn)備完(除去特殊情況),他們就一直等,直到運(yùn)動(dòng)員都在起跑線上,裁判喊口號(hào)后再開(kāi)始跑。這里的起跑線就是屏障,做完準(zhǔn)備工作的運(yùn)動(dòng)員都等在起跑線,直到其他運(yùn)動(dòng)員也把準(zhǔn)備工作做完!

二.函數(shù)接口 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

1.創(chuàng)建屏障

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結(jié)構(gòu)體指針

attr:屏障屬性結(jié)構(gòu)體指針

count:屏障等待的線程數(shù)目,即要count個(gè)線程都到達(dá)屏障時(shí),屏障才解除,線程就可以繼續(xù)執(zhí)行

2.等待

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

函數(shù)的成功返回值有2個(gè),第一個(gè)成功返回的線程會(huì)返回PTHREAD_BARRIER_SERIAL_THREAD,其他線程都返回0。可以用第一個(gè)成功返回的線程來(lái)做一些善后處理工作。

3.銷毀屏障

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

三.簡(jiǎn)單例子 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

寫(xiě)個(gè)簡(jiǎn)單的例子,主線程等待其他線程都完成工作后自己再向下執(zhí)行,類似pthread_join()函數(shù)!

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 /* 屏障總數(shù) */ 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后第一個(gè)返回\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)讓所有線程有足夠的時(shí)間把自己的返回值打印出來(lái)。編譯運(yùn)行:

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

這里有一點(diǎn)要注意:我們從運(yùn)行結(jié)果看出,主線程打印"所有線程工作已完成"之后,線程1,線程2還在運(yùn)行打印返回值。這個(gè)結(jié)果難免會(huì)誤解"主線程等待所有線程完成工作之后再向下執(zhí)行"。區(qū)分一點(diǎn)即可:等待只針對(duì)屏障之前的動(dòng)作,越過(guò)屏障后,無(wú)論是主線程,還是子線程都會(huì)并發(fā)執(zhí)行,如果非要讓子線程完完全全執(zhí)行完,可以再加個(gè)屏障到線程函數(shù)末尾,相應(yīng)主線程也要加!

總結(jié)

以上是生活随笔為你收集整理的linux线程同步(5)-屏障的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。