多线程编程——屏障

屏障是多线程同步的一种方法。barrier意为屏障或者栏杆,把先后到达的多个线程挡在同一栏杆前,直到所有线程到齐,然后撤下栏杆同时放行。先到达的线程将会阻塞,等到所有调用pthread_barrier_wait()函数的线程(数量等于屏障初始化时指定的count)都到达后,这些线程才会由阻塞状态进入就绪状态再次参与系统调度。屏障是基于条件变量和互斥锁实现的。主要操作包括:调用pthread_barrier_init()初始化一个屏障,其他线程调用pthread_barrier_wait(),所有线程到期后线程唤醒进入准备状态,屏障不在使用调用pthread_barrier_destroy()销毁一个屏障

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
/* 线程控制块 */
static pthread_t tid1;
static pthread_t tid2;
static pthread_t tid3;
/* 屏障控制块 */
static pthread_barrier_t barrier;
/* 函数返回值检查函数 */
static void check_result(char* str,int result)
{
	if (0 == result)
	{
		printf("%s successfully!\n",str);
	}
	else
	{
		printf("%s failed! error code is %d\n",str,result);
	}
}
/*线程1入口函数*/
static void* thread1_entry(void* parameter)
{
	int count = 0;
	printf("thread1 have arrived the barrier!\n");
	pthread_barrier_wait(&barrier); /* 到达屏障,并等待其他线程到达 */
	while (1)
	{
		/* 打印线程计数值输出 */
		printf("thread1 count: %d\n",count ++);
		/* 休眠2秒*/
		sleep(2);
	}
}
/*线程2入口函数*/
static void* thread2_entry(void* parameter)
{
	int count = 0;
	printf("thread2 have arrived the barrier!\n");
	pthread_barrier_wait(&barrier);
	while (1)
	{
		/* 打印线程计数值输出 */
		printf("thread2 count: %d\n",count ++);
		/* 休眠2秒*/
		sleep(2);
	}
}
/* 线程3入口函数 */
static void* thread3_entry(void* parameter)
{
	int count = 0;
	printf("thread3 have arrived the barrier!\n");
	pthread_barrier_wait(&barrier);
	while (1)
	{
		/* 打印线程计数值输出 */
		printf("thread3 count: %d\n",count ++);
		/* 休眠2秒*/
		sleep(2);
	}
}
/* 用户应用入口 */
int application_init()
{
	int result;
	pthread_barrier_init(&barrier,NULL,3);
	/*创建线程1,线程入口是thread1_entry, 属性参数设为NULL选择默认值,入口参数为NULL*/
	result = pthread_create(&tid1,NULL,thread1_entry,NULL);
	check_result("thread1 created",result);
	/*创建线程2,线程入口是thread2_entry, 属性参数设为NULL选择默认值,入口参数为NULL*/
	result = pthread_create(&tid2,NULL,thread2_entry,NULL);
	check_result("thread2 created",result);
	/*创建线程3,线程入口是thread3_entry, 属性参数设为NULL选择默认值,入口参数为NULL*/
	result = pthread_create(&tid3,NULL,thread3_entry,NULL);
	check_result("thread3 created",result);
	
	
	return 0;
}
int main()
{
	int i ;
	application_init();
	i=100;
	do{
		sleep(1);
	}while(i--);
}

运行结果:

-bash-3.2$ gcc -pthread barrier.c -o 8app
-bash-3.2$ ./8app
thread1 created successfully!
thread2 created successfully!
thread3 created successfully!
thread1 have arrived the barrier!
thread2 have arrived the barrier!
thread3 have arrived the barrier!
thread1 count: 0
thread2 count: 0
thread3 count: 0
thread1 count: 1
thread2 count: 1
thread3 count: 1
thread1 count: 2
thread2 count: 2
thread3 count: 2
thread2 count: 3
thread3 count: 3
thread1 count: 3
thread2 count: 4
thread3 count: 4
thread1 count: 4
thread2 count: 5
thread3 count: 5
thread1 count: 5
thread2 count: 6
thread3 count: 6
thread1 count: 6
thread2 count: 7
thread3 count: 7
thread1 count: 7
thread2 count: 8
thread3 count: 8
thread1 count: 8
thread2 count: 9
thread3 count: 9
thread1 count: 9

<think>我们刚刚讨论了自旋锁和信号量的区别,现在用户转向了线程同步中的另一个概念:屏障Barrier)。用户明确提到“我想了解线程同步中屏障的概念和用法”,并引用了Pythonthreading模块中Barrier的相关资料。用户的真实需求可能是:理解Barrier在多线程同步中的作用、适用场景及实现原理。结合引用内容看:引用[1]直接定义了Barrier的功能(让一组线程在某个点同步);引用[2][4]提到线程同步的必要性和Python具体实现。这说明用户希望得到理论与实践结合的解释,尤其关注Python场景。需要重点覆盖:1.核心功能:Barrier如何阻塞线程直到所有线程到达指定点2.与锁/信号量的区别:Barrier是集体同步(全员到齐才放行),而锁/信号量控制资源竞争3.典型使用场景:多阶段任务(如并行计算的分段同步)4.Python实现:结合引用[4]的代码片段说明用法5.潜在问题:如线程阻塞后的唤醒机制特别注意引用[3]提到的“乱序问题”和内存屏障(MemoryBarrier),但用户当前问题聚焦线程级同步而非底层内存模型,因此只需简要关联(避免过度展开硬件细节)。最终回答需突出三点:-原理:计数器+条件变量实现集体等待-场景:数据分片处理、多阶段算法-Python示例:threading.Barrier类的使用相关延伸问题可包括:Barrier与锁的性能对比、常见错误(如线程数不匹配)等。</think> ### 线程同步中的屏障Barrier)概念与原理 #### 1. **屏障的核心功能** 屏障Barrier)是一种**多线程集体同步**机制,其核心功能是: - **阻塞所有线程**直到**全部线程**都到达屏障点 - 一旦满足指定数量的线程到达(如$N$个),**自动唤醒所有线程继续执行** - 可添加**回调函数**在所有线程释放时执行(如资源初始化) ```python import threading # 创建屏障(3个线程必须全部到达) barrier = threading.Barrier(3, action=lambda: print("所有线程已就位!")) def worker(): print(f"线程{threading.current_thread().name}到达屏障") barrier.wait() # 阻塞等待其他线程 print(f"线程{threading.current_thread().name}继续执行") # 创建并启动3个线程 threads = [threading.Thread(target=worker) for _ in range(3)] for t in threads: t.start() for t in threads: t.join() ``` *输出示例:* ``` 线程Thread-1到达屏障 线程Thread-2到达屏障 线程Thread-3到达屏障 所有线程已就位! # 回调函数执行 线程Thread-1继续执行 线程Thread-2继续执行 线程Thread-3继续执行 ``` #### 2. **实现原理(基于条件变量)** 屏障通过组合**计数器**和**条件变量**实现: 1. **计数器**:记录已到达屏障的线程数(初始为0) 2. **条件变量**(`Condition`):控制线程阻塞/唤醒 3. **状态机**: - 当线程到达时:计数器$count = count + 1$ - 若$count < N$:线程阻塞在条件变量上 - 若$count = N$:唤醒所有线程,重置计数器 4. **内存屏障**:通过硬件级指令(如`mfence`)确保内存操作顺序,避免乱序执行[^3] #### 3. **典型应用场景** 1. **并行计算分阶段同步** ```mermaid graph LR A[数据加载] --> B[屏障1:等待所有数据就绪] B --> C[并行计算] C --> D[屏障2:等待所有计算完成] D --> E[结果合并] ``` 2. **分布式测试** 多台测试机同时到达检查点后才触发压力测试 3. **迭代算法** 每轮迭代需等待所有工作线程完成当前轮次 4. **资源协同初始化** 确保所有依赖资源就绪后同时启动服务 #### 4. **与锁/信号量的关键区别** | 机制 | 适用场景 | 同步目标 | |-------------|--------------------------|--------------------| | **屏障** | 多线程阶段同步 | 所有线程到达同一状态 | | **互斥锁** | 临界区保护 | 单线程访问资源 | | **信号量** | 控制并发访问数量 | 限制线程数量 | | **条件变量**| 事件驱动等待 | 特定状态触发 | > **关键优势**:屏障提供了**多线程集体进度协调**能力,这是其他同步原语无法直接实现的[^1][^4] #### 5. **注意事项** 1. **线程数必须匹配** 屏障初始化后**不能修改**需等待的线程数(如创建$N$个屏障但只有$N-1$个线程调用`wait()`将导致永久阻塞) 2. **超时机制** Python支持带超时的等待:`barrier.wait(timeout=5)` 3. **重置屏障** 通过`barrier.reset()`可强制重置屏障(中断当前等待线程) 4. **避免回调函数阻塞** 回调函数执行期间会阻塞所有线程释放,应保持轻量级 --- ### 相关问题 1. 如何在屏障中处理部分线程超时未到达的情况? 2. 屏障和线程池结合使用时有哪些最佳实践? 3. 内存屏障(Memory Barrier)如何影响多线程同步效率?[^3] 4. 在分布式系统中如何实现类似屏障的跨进程同步?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值