【编程】linux多线程同步机制——屏障

本文介绍了一种使用屏障(barrier)同步机制的并行排序算法实现,通过多个线程各自排序数据子集,然后合并结果,展示了如何在C语言中使用pthread库进行线程管理和同步。
复习:

线程同步方式:互斥量读写锁条件变量自旋锁屏障

屏障(barrier)是用户协调多个线程并行工作的同步机制。屏障允许每个线程等待,直到所有合作线程都到达某一点,然后从该点继续执行。

int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t * restrict attr, unsigned int count);
int pthread_barrier_destory(pthread_barrier_t * barrier);
int pthread_barrier_wait(pthread_barrier_t *barrier)
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <limits.h>
#include <sys/time.h>

#define NTHR 8
#define NUMMUM 8000000L
#define TNUM (NUMMUM/NTHR)

long nums[NUMMUM];
long snums[NUMMUM];

pthread_barrier_t b;

#ifdef SOLARIS
#define heapsort qsort
#else
extern int heapsort(void *,size_t, size_t,int(*)(const void*,const void*));
#endif

int complong(const void *arg1, const void *arg2)
{
	long l1=*(long*)arg1;
	long l2=*(long*)arg2;

	if(l1=l2)
		return 0;
	else if (l1<l2)
		return -1;
	else
		return 1;
}

void * thr_fn(void*arg)
{
	long idx=(long)arg;

	heapsort(&nums[idx], TNUM, sizeof(long), complong);
	pthread_barrier_wait(&b);
	return ((void*)0);
}


void merge()
{
	long idx[NTHR];
	long i,minidx,sidx,num;

	for(i = 0; i < NTHR; i++)
	{
		idx[i] = i * TNUM;
	}

	for (sidx = 0; sidx < NUMMUM; sidx++)
	{
		num = LONG_MAX;
		for (i=0; i < NTHR; i++)
		{
			if ((idx[i] < (i+1)*TNUM) && (nums[idx[i]] < num)) {
				num = nums[idx[i]];
				minidx = i;
			}
			snums[sidx] = nums[idx[minidx]];
			idx[minidx]++;
		}
	}
}


int main(int argc, char *argv[])
{
	unsigned long i;
	struct timeval start,end;
	long long startusec, endusec;
	double elapsed;
	int err;
	pthread_t tid;

	srandom(1);
	for (i=0; i < NUMMUM; i++)
	{
		nums[i] = random();
	}

	gettimeofday(&start, NULL);
	pthread_barrier_init(&b, NULL, NTHR+1);
	for(i = 0; i < NTHR; i++)
	{
		err = pthread_create(&tid, NULL, thr_fn, (void*)(i*TNUM));
		if (err != 0)
		{
			printf("can't create\n");
		}
	}
	pthread_barrier_wait(&b);
	merge();
	gettimeofday(&end, NULL);

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

	for (i = 0; i < NUMMUM; i++)
	{
		printf("%ld\n",snums[i]);
	}

	return 0;
}




### C语言多线程并发编程实现方法 #### 使用POSIX线程(pthreads) 在Linux环境中,C语言多线程编程主要依靠POSIX线程库(pthread)。此库提供了创建、管理和控制线程的功能。为了启动一个新的线程,需调用`pthread_create()`函数并传递必要的参数给新线程执行的任务函数[^1]。 ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> void* thread_function(void *arg) { printf("Thread is running\n"); pthread_exit(NULL); } int main() { pthread_t thread; int ret = pthread_create(&thread, NULL, thread_function, NULL); if (ret != 0) { fprintf(stderr, "Error creating thread\n"); exit(EXIT_FAILURE); } pthread_join(thread, NULL); // Wait for the created thread to finish return 0; } ``` 这段代码展示了如何定义一个简单的线程入口点——即`thread_function`,并通过`pthread_create()`来初始化它。之后主线程会等待子线程完成工作后再继续运行。 #### 同步与互斥锁 当多个线程访问共享资源时,可能会引发竞态条件等问题。为了避免这种情况的发生,可以采用互斥量(`mutex`)来进行同步操作。下面的例子说明了怎样声明和使用互斥变量保护临界区: ```c pthread_mutex_t mutex; // 初始化互斥量 if(pthread_mutex_init(&mutex, NULL) != 0){ puts("Mutex init failed"); return 1; } // 进入临界区之前加锁 pthread_mutex_lock(&mutex); /* Critical section code here */ // 离开临界区后解锁 pthread_mutex_unlock(&mutex); // 销毁互斥量 pthread_mutex_destroy(&mutex); ``` 上述片段中包含了对互斥对象生命周期的操作:从创建到销毁,并且演示了进入/退出临界区的方式[^4]。 #### 高级并发工具应用 除了基本的线程管理和同步外,还可以借助一些更复杂的结构如计数信号灯(CountDownLatch)或循环屏障(CyclicBarrier),它们有助于协调不同线程之间的协作行为。虽然这类功能并非直接由POSIX标准提供,但在某些第三方库中有相应的实现可供选用[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值