Как реализовать барьер с помощью семафоров posix?
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) раз она устанавливает (+1) для семафоров в массиве 'arr' и переходит в спящий режим (вызывая sem_wait). N-й раз он уменьшает семафоры в 'arr' и ДОЛЖЕН (как я ожидаю) разбудить потоки [0..bar.number-1], размещающие +1 для семафоров в массиве 'cont'. Это не работает как барьер.
pthread_self()-2
? Значение, возвращаемое изpthread_self()
, является непрозрачным идентификатором. Откуда вы знаете, что можете вычесть из него 2 и использовать его как индекс массива? - person Celada   schedule 23.12.2012pthread_self()
: Идентификаторы потоков следует считать непрозрачными. - person Celada   schedule 23.12.2012bar.counter
нужно защитить от одновременных обновлений с помощью мьютекса? - person Celada   schedule 23.12.2012bar.counter
не защищен от одновременной модификации несколькими потоками. Я мог упустить что-то еще (о параллельных алгоритмах трудно рассуждать), но вам следует начать сbar.counter
. Затем, я думаю, вы можете добавить вывод отладки, чтобы показать состояние до/после ожидания каждого потока, и, возможно, вывод покажет состояние, которого вы не ожидали, что будет подсказкой. - person Celada   schedule 24.12.2012