信号量实现barrier"/>
pthread分别使用互斥量、条件变量、信号量实现barrier
导入
在多线程编程里,路障(Barrier)是一个非常有利的工具。大概有以下几种应用场景;
- 希望各线程重新同步。有一些线程可能在某些阶段执行的相对较快,如果我们需要它们同步进入下一阶段,就要用到Barrier。
- 调试程序。多线程程序不像单线程程序那样可以很方便进行调试。有些时候一些线程的一些变量值被不经意修改导致在运行下一阶段时出现bug。这时候就需要使用Barrier,让大家都停一停,打印自己的变量信息。
pthread不提供路障的实现,需要我们自己手动实现。本文提供了三种实现方式。
建模
barrier就是指各线程都在程序的某一个点停一下,等大家都到了这个点后,再一块执行后续的程序。
所以,可以把大家都到了这个点看做是一个信号,如果线程没有接受到这个信号就阻塞,否则就继续执行。
我们需要借助计数器counter。如果counter的值==线程数,那么就可以发出信号了。
mutex实现barrier
mutex主要功能是协调临界区的访问,实现barrier不在它的能力范围之内其实。
操作系统并发性(二):锁
pthread_mutex_t mutex;
void Barrier_mutex()
{pthread_mutex_lock(&mutex);count = count + 1;if (count == thread_count)count = 0;pthread_mutex_unlock(&mutex);while (count == thread_count);
}
该实现方式通过mutex协调count的更新,while自旋检查信号。
最大的问题就在于等待的进程没有休眠,会浪费CPU时间片。
sem实现barrier
信号量sem非常灵活,调用机制也很简单。
count_sem起到锁的作用,协调count的读写。
barrier_sem是“所有线程都到达执行点”的信号。先到达的线程进入休眠状态,由最后一个线程将它们唤醒。
sem_t barrier_sem, count_sem;
void Barrier_sem()
{ sem_wait(&count_sem);if (count == thread_count - 1){count = 0;sem_post(&count_sem);for (int i = 0; i < thread_count; i++)sem_post(&barrier_sem);}else{count += 1;sem_post(&count_sem);sem_wait(&barrier_sem);}
}
cond实现barrier
操作系统并发性(三):条件变量
实现思路就是将counter == thread_count看做条件,然后套用条件变量的使用模板即可。最后一个到达的线程使用pthread_cond_broadcast唤醒之前到达的所有线程。
pthread_mutex_t mutex;
pthread_cond_t cond;
void Barrier_cond()
{pthread_mutex_lock(&mutex);count++;if (count == thread_count){count = 0;pthread_cond_broadcast(&cond);}else{pthread_cond_wait(&cond, &mutex);}pthread_mutex_unlock(&mutex);
}
更多推荐
pthread分别使用互斥量、条件变量、信号量实现barrier
发布评论