1. 围栏机制介绍
Linux线程里还支持一个围栏机制--也就是屏障功能。这个围栏机制,可以设置等待的线程数量,当指定数量的线程都到齐之后再全部唤醒—放行。它的的功能和它的名字是匹配的,就是围栏,就像在赛跑比赛场上,要进行比赛时,必须等待所有运动员都到齐全了,都到起跑线上了,然后一声令下,大家再一起跑出去。
在Linux线程里的屏障功能由pthread_barrier
系列函数实现,在<pthread.h>中定义,功能主要是用于多线程的同步。
2. 围栏机制相关的函数介绍
相关的函数接口如下:
#include <pthread.h>
1. 销毁围栏
int pthread_barrier_destroy(pthread_barrier_t *barrier);
参数:
pthread_barrier_t*就是围栏机制的结构。
2. 初始化围栏
int pthread_barrier_init(pthread_barrier_t *restrict barrier,const pthread_barrierattr_t *restrict attr, unsigned count);
参数: unsigned count 表示需要等待的线程数量,必须有这么多线程都在等待了,栏杆才会放行。
3. 等待条件成立
int pthread_barrier_wait(pthread_barrier_t *barrier);
功能: 阻塞等待线程的数量到齐,这个数量在初始化的时候设置,全部成立了,再返回。
3. 围栏机制使用案例1
下面代码里设置栏杆等待线程数量为10个,然后启动循环创建10个线程,当10个线程创建完毕之后,一起运行。
设置线程为分离属性。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
pthread_barrier_t barrier;
/*
线程工作函数
*/
void *thread_work_func(void *dev)
{
int i=(int)dev;
printf("第%d个线程等待运行...\n",i);
//等待线程的数量
pthread_barrier_wait(&barrier);
printf("第%d个线程开始运行...\n",i);
}
int main(int argc,char **argv)
{
//初始化栏杆机制
pthread_barrier_init(&barrier,NULL,10);
/*创建子线程*/
pthread_t thread_id;
int i;
for(i=0;i<10;i++)
{
if(pthread_create(&thread_id,NULL,thread_work_func,(void*)i)!=0)
{
printf("子线程%d创建失败.\n",i);
return -1;
}
//设置线程的分离属性
pthread_detach(thread_id);
sleep(1);
}
pause(); //暂停
//销毁围栏机制
pthread_barrier_destroy(&barrier);
return 0;
}
4. 围栏机制使用案例2
下面代码里设置栏杆等待线程数量为10个,然后启动循环创建10个线程,每个新的线程创建之后,都会在函数里打印第几个线程准备运行,当10个线程创建完毕之后,都在等待了,然后再一起放行。
设置线程为结合属性。
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include <signal.h>
pthread_barrier_t barrier;
//线程工作函数
void *thread_work_func(void *arg)
{
printf("线程%lu准备运行.\n",pthread_self());
//等待人员到齐
pthread_barrier_wait(&barrier);
printf("线程%lu开始运行.\n",pthread_self());
}
int main(int argc,char **argv)
{
pthread_barrier_init(&barrier,NULL,10);
/*1. 创建线程*/
pthread_t thread_id[10];
int i;
for(i=0;i<10;i++)
{
if(pthread_create(&thread_id[i],NULL,thread_work_func,NULL))
{
printf("%d线程创建失败.\n",i);
return 0;
}
sleep(1);
}
/*2. 等待子线程结束*/
for(i=0;i<10;i++)
{
pthread_join(thread_id[i],NULL);
}
pthread_barrier_destroy(&barrier);
return 0;
}