在Linux系統(tǒng)中提供了多種同步機(jī)制,本文主要講講如何使用pthread_barrier_xxx系列函數(shù)來(lái)實(shí)現(xiàn)多線程之間進(jìn)行同步的方法。
函數(shù)定義
pthread_barrier_xxx系列函數(shù)中的barrier可意為柵欄,可以理解為該柵欄能夠把先后到達(dá)的多個(gè)線程阻擋在同一柵欄前,直到所有線程到齊,柵欄才會(huì)放行,否則到達(dá)此處的線程將被阻塞。
pthread_barrier_xxx系列函數(shù)在
//初始化柵欄,負(fù)責(zé)指定柵欄要等待的線程個(gè)數(shù), //柵欄需要等待count個(gè)線程都到達(dá)柵欄時(shí),才會(huì)全部一起放行 intpthread_barrier_init(pthread_barrier_t*restrict, constpthread_barrierattr_t*restrict,unsignedcount); //pthread_barrier_wait()函數(shù)會(huì)同步所有參與barrier的線程, //調(diào)用該函數(shù)的線程會(huì)阻塞住,直到pthread_barrier_init()中指定 //數(shù)量的線程調(diào)用了pthread_barrier_wait()函數(shù),所有線程才會(huì)同時(shí)往下執(zhí)行 intpthread_barrier_wait(pthread_barrier_t*barrier); //釋放pthread_barrier_init()函數(shù)申請(qǐng)的資源 intpthread_barrier_destroy(pthread_barrier_t*barrier);
應(yīng)用場(chǎng)景
在應(yīng)用程序啟動(dòng)的時(shí)候,需要?jiǎng)?chuàng)建一個(gè)或者多個(gè)線程去完成不同功能的處理。子線程啟動(dòng)之后,需要等待主進(jìn)程完成基礎(chǔ)的配置之后各個(gè)子線程才能正常工作。所以這里就存在一個(gè)問題要解決,各個(gè)子線程如何等待主進(jìn)程完成工作后,才繼續(xù)往下執(zhí)行呢?
為了解決上述場(chǎng)景的問題,我們可以在調(diào)用pthread_barrier_init()時(shí)指定n+1個(gè)等待,其中n是線程數(shù)。而在每個(gè)線程執(zhí)行函數(shù)的開始調(diào)用pthread_barrier_wait()。這樣主進(jìn)程在調(diào)用pthread_create()創(chuàng)建子線程后,子線程運(yùn)行到pthread_barrier_wait()后將被阻塞,線程都停下來(lái)等待最后一個(gè)pthread_barrier_wait()函數(shù)被調(diào)用。最后一個(gè)pthread_barrier_wait()函數(shù)由主進(jìn)程或者其他子線程在它覺得合適的時(shí)候調(diào)用就行。最后這個(gè)pthread_barrier_wait()有點(diǎn)像跑步運(yùn)動(dòng)時(shí)的起步槍,只有最后這個(gè)pthread_barrier_wait()函數(shù)被調(diào)用,其他被阻塞的線程就能夠繼續(xù)運(yùn)行。
使用實(shí)例
下面的程序,在main()函數(shù)中,pthread_barrier_init()指定2+1個(gè)等待,接著創(chuàng)建了2個(gè)線程,然后主進(jìn)程延時(shí)6秒,之后調(diào)用pthread_barrier_wait()來(lái)讓線程接著運(yùn)行,程序如下:
/* ******************************************************************************** *描述:pthread_barrier_xxx程序示例 *Use:gccpthread_barrier_xxx.c-lpthread *./a.out *By:AilsonJack *Date:2016.03.24 *CSDN//blog.csdn.net/jackailson ******************************************************************************** */ #include#include #include #include //線程?hào)艡?pthread_barrier_tbarrier; void*task1(void*arg); void*task2(void*arg); intmain(void) { pthread_ttask1_tid; pthread_ttask2_tid; pthread_attr_ttask1_attr; pthread_attr_ttask2_attr; //初始化線程屬性 pthread_attr_init(&task1_attr); pthread_attr_init(&task2_attr); //初始化柵欄 pthread_barrier_init(&barrier,NULL,2+1);//2+1個(gè)等待 //創(chuàng)建線程1 pthread_create(&task1_tid,&task1_attr,task1,NULL); //創(chuàng)建線程2 pthread_create(&task2_tid,&task2_attr,task2,NULL); printf("mainprocesswillsleep6s. "); sleep(6);//等待6s,讓task1和task2都阻塞住了,再運(yùn)行主線程 //主線程調(diào)用pthread_barrier_wait()函數(shù)之后,已經(jīng)達(dá)到了 //pthread_barrier_init()函數(shù)設(shè)置的3個(gè)等待條件,此時(shí)調(diào)用 //pthread_barrier_wait()函數(shù)的主線程不會(huì)被阻塞,task1和 //task2也將繼續(xù)運(yùn)行. pthread_barrier_wait(&barrier); pthread_join(task1_tid,NULL); pthread_join(task2_tid,NULL); pthread_barrier_destroy(&barrier); } void*task1(void*arg) { printf("task1willbeblocked. "); pthread_barrier_wait(&barrier);//線程將被阻塞在這里 printf("task1isrunning. "); sleep(3);//延時(shí)3s pthread_exit(NULL); } void*task2(void*arg) { printf("task2willbeblocked. "); pthread_barrier_wait(&barrier);//線程將被阻塞在這里 printf("task2isrunning. "); sleep(3);//延時(shí)3s pthread_exit(NULL); }
程序的運(yùn)行結(jié)果如下圖所示:
審核編輯:劉清
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
588瀏覽量
27262 -
多線程
+關(guān)注
關(guān)注
0文章
276瀏覽量
19878
原文標(biāo)題:Linux應(yīng)用編程-pthread_barrier_xxx介紹
文章出處:【微信號(hào):嵌入式那些事,微信公眾號(hào):嵌入式那些事】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論