存在需求冲突:屏障语义要求所有线程in
继续运行,而当线程在执行块之间共享(可能位于不同的屏障内)时,关闭需要终止。
我建议用支持外部cancel
调用的自定义实现替换屏障。
示例(可能无法运行,但想法...):
struct _barrier_entry
{
pthread_cond_t cond;
volatile bool released;
volatile struct _barrier_entry *next;
};
typedef struct
{
volatile int capacity;
volatile int count;
volatile struct _barrier_entry *first;
pthread_mutex_t lock;
} custom_barrier_t;
初始化:
int custom_barrier_init(custom_barrier_t *barrier, int capacity)
{
if (NULL == barrier || capacity <= 0)
{
errno = EINVAL;
return -1;
}
barrier->capacity = capacity;
barrier->count = 0;
barrier->first = NULL;
return pthread_mutex_init(&barrier->lock, NULL);
return -1;
}
帮手:
static void _custom_barrier_flush(custom_barrier_t *barrier)
{
struct _barrier_entry *ptr;
for (ptr = barrier->first; NULL != ptr;)
{
struct _barrier_entry *next = ptr->next;
ptr->released = true;
pthread_cond_signal(&ptr->cond);
ptr = next;
}
barrier->first = NULL;
barrier->count = 0;
}
阻塞等待:
int custom_barrier_wait(custom_barrier_t *barrier)
{
struct _barrier_entry entry;
int result;
pthread_cond_init(&barrier->entry, NULL);
entry->next = NULL;
entry->released = false;
pthread_mutex_lock(&barrier->lock);
barrier->count++;
if (barrier->count == barrier->capacity)
{
_custom_barrier_flush(barrier);
result = 0;
}
else
{
entry->next = barrier->first;
barrier->first = entry;
while (true)
{
pthread_cond_wait(&entry->cond, &barrier->lock);
if (entry->released)
{
result = 0;
break;
}
if (barrier->capacity < 0)
{
errno = ECANCELLED;
result = -1;
break;
}
}
}
pthread_mutex_unlock(&barrier->lock);
pthread_cond_destroy(&entry->cond);
return result;
}
消除:
int custom_barrier_cancel(custom_barrier_t *barrier)
{
pthread_mutex_lock(barrier->lock);
barrier->capacity = -1;
_custom_barrier_flush(barrier);
pthread_mutex_unlock(barrier->lock);
return 0;
}
所以线程代码可以在循环中运行,直到调用ECANCELLED
后出错。custom_barrier_wait