如何使用POSIX信号量实现屏障?
当函数my_barrier_wait被调用时,首先(N-1)次它会对数组'arr'中的信号量进行设置(+1),并进入休眠状态(调用sem_wait)。第N次会将'arr'数组中的信号量减少,并且应该(按照我的期望)唤醒[0..bar.number-1]线程,在'cont'数组中为信号量发布+1。 但是它的工作方式不像屏障。
void my_barrier_init(int a){
int i;
bar.number = a;
bar.counter = 0;
bar.arr = (sem_t*) malloc(sizeof(sem_t)*bar.number);
bar.cont = (sem_t*) malloc(sizeof(sem_t)*bar.number);
for(i = 0; i < bar.number; i++){
sem_init(&bar.arr[i], 0, 0);
sem_init(&bar.cont[i], 0, 0); }
}
void my_barrier_wait(){
int i;
bar.counter++;
if(bar.number == bar.counter){
for(i = 0; i < bar.number-1; i++){ sem_wait(&bar.arr[i]); }
for(i = 0; i < bar.number-1; i++){ sem_post(&bar.cont[i]); }
bar.counter = 0;
}else{
sem_post(&bar.arr[pthread_self()-2]);
sem_wait(&bar.cont[pthread_self()-2]);
}
}
当函数my_barrier_wait被调用时,首先(N-1)次它会对数组'arr'中的信号量进行设置(+1),并进入休眠状态(调用sem_wait)。第N次会将'arr'数组中的信号量减少,并且应该(按照我的期望)唤醒[0..bar.number-1]线程,在'cont'数组中为信号量发布+1。 但是它的工作方式不像屏障。
pthread_self()
的手册中可以看出:"线程标识符应被视为不透明。" - Celadabar.counter
免受并发更新的影响? - Celadabar.counter
没有受到保护,可能会被多个线程同时修改。我可能会忽略一些细节(并行算法很难理解),但你应该从bar.counter
开始着手。然后,我猜你可以添加调试输出,显示每个线程在等待之前/之后的状态,也许输出会展示一种你没想到的状态,这就是一个线索。 - Celada