之前也介紹過線程之間的同步和互斥,接下來看一下barrier
过牙。假設(shè)我們要執(zhí)行一個包含兩個階段的多線程計算甥厦,但是我們不希望在完成第一階段之前進(jìn)入第二階段。我們可以使用一種稱為屏障(barrier)的同步方法寇钉。當(dāng)線程到達(dá)barrier時刀疙,它將在barrier處等待,直到所有線程到達(dá)barrier摧莽,然后它們將一起進(jìn)行庙洼。
如何理解barrier呢?就像和一些朋友一起遠(yuǎn)足。大家會會記下有多少個朋友油够,并同意在每個山峰的頂部等彼此蚁袭。假設(shè)你是第一個到達(dá)第一個山頂?shù)娜耍銓⒃陧敳康绕渌笥咽АK麄儠灰坏竭_(dá)頂部揩悄,但是直到最后一個人到達(dá)之前,沒有人會繼續(xù)走鬼悠。等所有人都到了之后删性,大家將繼續(xù)進(jìn)行。
Pthreads具有實現(xiàn)該功能的函數(shù)pthread_barrier_wait()
焕窝。需要聲明一個pthread_barrier_t
變量蹬挺,并使用pthread_barrier_init()
對其進(jìn)行初始化。 pthread_barrier_init()
將將要參與barrier的線程數(shù)作為參數(shù)它掂。
下面是一個示例程序:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#define THREAD_COUNT 4
pthread_barrier_t mybarrier;
void* threadFn(void *id_ptr) {
int thread_id = *(int*)id_ptr;
int wait_sec = 1 + rand() % 5;
printf("thread %d: Wait for %d seconds.\n", thread_id, wait_sec);
sleep(wait_sec);
printf("thread %d: I'm ready...\n", thread_id);
pthread_barrier_wait(&mybarrier);
printf("thread %d: going!\n", thread_id);
return NULL;
}
int main() {
int i;
pthread_t ids[THREAD_COUNT];
int short_ids[THREAD_COUNT];
srand(time(NULL));
pthread_barrier_init(&mybarrier, NULL, THREAD_COUNT + 1);
for (i=0; i < THREAD_COUNT; i++) {
short_ids[i] = i;
pthread_create(&ids[i], NULL, threadFn, &short_ids[i]);
}
printf("main() is ready.\n");
pthread_barrier_wait(&mybarrier);
printf("main() is going!\n");
for (i=0; i < THREAD_COUNT; i++) {
pthread_join(ids[i], NULL);
}
pthread_barrier_destroy(&mybarrier);
return 0;
}