且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Linux系统编程-(pthread)线程通信(围栏机制)

更新时间:2022-05-20 03:42:43

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;
}