Linux线程同步------屏障

本文介绍线程屏障在Linux下的使用方法及实例,通过对比不同线程数量对数组初始化时间的影响,展示了线程屏障如何提高多线程程序的效率。

屏障是Linux中协调多个线程并行工作的同步机制,屏障允许每个线程等待直到所有的合作线程到达某一点,然后继续从该点执行,pthread_join是一种屏障但只允许一个线程等待,pthread_barrier允许任意数量的线程等待!

pthread_barrier_init(pthread_barrier_t *屏障,属性,unsigned int 屏障计数值);

pthread_barrier_wait(pthread_barrier_t *屏障):在每个线程中调用则计数值加一并将当前线程阻塞在这里,直到计数值达到初始化时设定的值;

线程屏障使用实例:

1、若对一个有800万的数组进行排序,在一个线程中完成需要很长的时间,若采用线程屏障,用8个线程分别对100万个数进行堆排序,然后在主线程中进行merge合并操作,耗时将节省6倍!

2、如下的例子是对一个800万个元素的数组进行初始化,分别采用1、4、8个线程来完成,发现采用8个线程耗时最短。

/*
程序功能:
	创建一个动态数组,给数组赋初值,创建NUM_THREAD个线程,为长度为SIZE的数组初始化,通过(线程屏障同步)
	当所有线程处理完后则打印整个数组的值。通过时间计数来比较所花费的时间。
当采用8个线程时花费sort took 0.0958 seconds
当采用四个线程时
	thread -1249961072 done job.
	thread -1260450928 done job.
	thread -1239471216 done job.
	thread -1270944880 done job.
	sort took 0.1104 seconds
当采用一个线程时
	thread -1239983216 done job.
	sort took 0.2567 seconds
*/
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define SIZE 8000000L   //数组长度
#define NUM_THREAD 8 //线程个数
#define SIZE_PER (SIZE/NUM_THREAD)//每个线程要处理的数组长度
pthread_barrier_t barrier;//定义屏障
int *a;
/*每个线程的线程处理函数*/
void * thr_fun(void *arg)
{
	long n = (long)arg;	
	long i;
	for(i=n;i<n+SIZE_PER;i++) {
		a[i] = i;
		
	}
	printf("thread %d done job.\n",pthread_self());
	pthread_barrier_wait(&barrier);
	return ((void *)1);
}

int main()
{
	pthread_t tid;
	struct timeval start,end;
	long long startusec,endusec;
	double elapsed;
	int i;
	a = (int *)malloc(SIZE*sizeof(int));  //动态分配数组
	pthread_barrier_init(&barrier,NULL,NUM_THREAD+1);//初始化线程屏障计数为子线程个数加上主线程
	gettimeofday(&start,NULL);//获得起始时间
	for(i=0;i<NUM_THREAD;i++)
	{
		pthread_create(&tid,NULL,thr_fun,(void *)(i*SIZE_PER));//创建子线程
	}
	pthread_barrier_wait(&barrier);//等待所有子线程处理完成
	gettimeofday(&end,NULL);//获得结束时间
	for(i=0;i<SIZE;i++)//打印数组内容
	//printf("%d ",a[i]);
	
	startusec = start.tv_sec * 1000000 +  start.tv_usec;
	endusec = end.tv_sec * 1000000 + end.tv_usec;
	elapsed = (double)(endusec-startusec)/1000000.0;//计算处理所花费的时间
	printf("sort took %.4f seconds\n",elapsed);

	return 0;
}

<think>好的,我现在需要回答用户关于Linux环境下线程同步的方法和机制的问题。首先,我得回忆一下Linux提供的线程同步机制有哪些。根据之前提供的引用内容,用户提到的引用[1]和[4]都提到了条件变量,而引用[2]和[3]还提到了互斥锁、信号量、读写锁等。需要把这些机制都涵盖进去。 首先,我应该列出主要的同步方法,比如互斥锁、条件变量、信号量、读写锁和屏障。然后,每个方法需要给出简要的解释,并附上示例代码,这样用户能更直观地理解。同时,根据用户的要求,行内数学公式用$...$,独立公式用$$...$$,但这里可能数学公式不多,主要是代码示例。需要确保代码语法正确,使用中文回答,并在适当的地方添加引用标识。 接下来,我需要检查每个同步机制的正确用法。例如,互斥锁使用pthread_mutex_t,条件变量配合互斥锁使用,信号量有POSIX和System V两种,但通常推荐POSIX信号量。读写锁用pthread_rwlock_t,屏障用pthread_barrier_t。每个示例代码的结构应该正确,比如初始化、加锁解锁、销毁等步骤。 然后,要注意引用对应的来源。比如,互斥锁和条件变量在引用[1]、[2]、[3]、[4]中都有提及,需要合理分配引用标记。例如,条件变量在引用[1]和[3]中都有提到,所以可能在解释条件变量时加上[^1][^3]。 可能遇到的问题包括如何简明扼要地解释每个机制,同时保持示例代码的正确性。例如,信号量的示例可能需要展示sem_wait和sem_post的使用,而屏障则需要展示pthread_barrier_wait的用法。此外,还需要注意线程安全函数的提及,如引用[2]中的可重入函数,但用户的问题主要关注同步机制,所以可能不需要深入讨论线程安全函数。 最后,生成的相关问题需要围绕线程同步的方法展开,比如性能比较、死锁避免、适用场景等。确保问题与用户的问题相关,并且能够引导进一步的学习。 总结步骤: 1. 列出Linux下的线程同步机制:互斥锁、条件变量、信号量、读写锁、屏障。 2. 对每个机制进行简要说明,给出代码示例。 3. 添加对应的引用标记。 4. 生成相关问题。</think>### Linux 环境下线程同步的方法与示例 Linux 提供了多种线程同步机制,用于解决多线程并发访问共享资源时的互斥和协作问题。以下是常见方法及其实现示例: --- #### 1. **互斥锁(Mutex)** 通过锁机制保证同一时间只有一个线程访问共享资源。 **示例代码**: ```c #include <pthread.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void* thread_func(void* arg) { pthread_mutex_lock(&mutex); // 加锁 // 访问共享资源 pthread_mutex_unlock(&mutex); // 解锁 return NULL; } ``` **特点**:简单高效,但可能引发死锁[^2][^4]。 --- #### 2. **条件变量(Condition Variable)** 用于线程间通信,当某个条件满足时唤醒等待的线程。需与互斥锁配合使用。 **示例代码**: ```c #include <pthread.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; bool flag = false; void* consumer(void* arg) { pthread_mutex_lock(&mutex); while (!flag) { pthread_cond_wait(&cond, &mutex); // 等待条件成立 } // 条件满足后执行操作 pthread_mutex_unlock(&mutex); return NULL; } void* producer(void* arg) { pthread_mutex_lock(&mutex); flag = true; pthread_cond_signal(&cond); // 通知等待线程 pthread_mutex_unlock(&mutex); return NULL; } ``` **应用场景**:生产者-消费者模型。 --- #### 3. **信号量(Semaphore)** 通过计数器控制对共享资源的访问,支持多线程同时访问(但数量受限)。 **示例代码**: ```c #include <semaphore.h> sem_t sem; void* thread_func(void* arg) { sem_wait(&sem); // P操作(计数器减1) // 访问共享资源 sem_post(&sem); // V操作(计数器加1) return NULL; } // 初始化信号量(初始值为2) sem_init(&sem, 0, 2); ``` **特点**:适用于限流场景,如连接池管理。 --- #### 4. **读写锁(Read-Write Lock)** 允许多个读线程同时访问,但写线程独占资源。 **示例代码**: ```c #include <pthread.h> pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; void* reader(void* arg) { pthread_rwlock_rdlock(&rwlock); // 读锁 // 读取共享资源 pthread_rwlock_unlock(&rwlock); return NULL; } void* writer(void* arg) { pthread_rwlock_wrlock(&rwlock); // 写锁 // 修改共享资源 pthread_rwlock_unlock(&rwlock); return NULL; } ``` **适用场景**:读多写少的场景(如缓存系统)。 --- #### 5. **屏障(Barrier)** 同步多个线程,直到所有线程到达某个点后才继续执行。 **示例代码**: ```c #include <pthread.h> pthread_barrier_t barrier; void* thread_func(void* arg) { // 执行部分任务 pthread_barrier_wait(&barrier); // 等待其他线程 // 继续后续任务 return NULL; } // 初始化屏障(等待3个线程) pthread_barrier_init(&barrier, NULL, 3); ``` **应用场景**:并行计算中多阶段任务同步[^4]。 --- ### 对比与选择 | 机制 | 适用场景 | 复杂度 | |--------------|----------------------------|--------| | 互斥锁 | 简单互斥访问 | 低 | | 条件变量 | 线程间条件协作 | 中 | | 信号量 | 限流或资源池管理 | 中 | | 读写锁 | 读多写少场景 | 中 | | 屏障 | 多线程分阶段同步 | 高 | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值