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

简介: Linux线程里还支持一个围栏机制--也就是屏障功能。这个围栏机制,可以设置等待的线程数量,当指定数量的线程都到齐之后再全部唤醒—放行。它的的功能和它的名字是匹配的,就是围栏,就像在赛跑比赛场上,要进行比赛时,必须等待所有运动员都到齐全了,都到起跑线上了,然后一声令下,大家再一起跑出去。

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;
}
目录
相关文章
|
Java API 微服务
为什么虚拟线程将改变Java并发编程?
为什么虚拟线程将改变Java并发编程?
499 83
|
9月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
332 6
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
451 0
|
10月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
615 16
|
9月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
805 0
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
482 67
|
存储 Linux
Linux内核中的current机制解析
总的来说,current机制是Linux内核中进程管理的基础,它通过获取当前进程的task_struct结构的地址,可以方便地获取和修改进程的信息。这个机制在内核中的使用非常广泛,对于理解Linux内核的工作原理有着重要的意义。
675 11
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
328 26
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
347 17