我正在尝试使用条件变量为线程实现屏障系统,但有一个警告,即一旦屏障填充,第一个到达的线程必须写入资源以与其余线程共享。问题是,当我运行程序时,广播调用不会唤醒大多数线程,我花了很长时间尝试调试它,但没有成功。
如果我删除了对 add_codeword() 的调用,那么线程就会完美地组合在一起,我怀疑这与 add_codeword() 包含大约 4 秒的等待有关。
void join_meetup(char *value, int len) {
pthread_mutex_lock(&mut);
if(++count < grp_size) {
if(count == 1) {
add_codeword(value, len); //<=== This has a wait() all of 4 seconds.
}
int curr_group = group;
while(curr_group == group) {
pthread_cond_wait(&queue, &mut);
}
}else{
if(meet_ord == MEET_LAST) {
add_codeword(value, len);
}
count = 0; //Reset group counter.
group++; //Increment the group num
pthread_cond_broadcast(&queue);
}
read_resource(&code_list[(group-1) % CODE_SIZE], value, len);
pthread_mutex_unlock(&mut);
}
以下是组大小设置为 3 的示例输出:
Group 1: 1
Group 1: 1
Group 1: 1
INISHED WRITING CODE! 4
Group 2: 4
INISHED WRITING CODE! 7
Group 3: 7
Group 3: 7
Group 3: 7
Group 4: 10
FINISHED WRITING CODE! 13
Group 4: 10
Group 4: 10
Group 5: 13
FINISHED WRITING CODE! 16
Group 5: 13
Group 5: 13
Group 5: 13
Group 5: 13
如您所见,组 2 只有 1 个线程,组 5 有 5 个线程。
谢谢
最佳答案
您的代码中似乎存在竞争条件。特别是,您似乎假设当线程从其条件循环中唤醒时,变量“group”将比它们进入时高1,但这并不总是正确的。想象一下,当您有非常“惰性”的线程,在收到信号后需要很长时间才能实际运行时,会发生什么。当他们到达这条线时:
read_resource(&code_list[(group-1) % CODE_SIZE], value, len);
与特定线程进入时相比,“group”可能已被后续线程更新多次次。试试这个:
void join_meetup(char *value, int len)
{
pthread_mutex_lock(&mut);
int my_group = group;
if (++count < grp_size)
{
if (count == 1)
add_codeword(value, len); //<=== This has a wait() all of 4 seconds.
while (group == my_group)
pthread_cond_wait(&queue, &mut);
}
else
{
if (meet_ord == MEET_LAST)
add_codeword(value, len);
count = 0; //Reset group counter.
group++; //Increment the group num
pthread_cond_broadcast(&queue);
}
read_resource(&code_list[my_group % CODE_SIZE], value, len);
pthread_mutex_unlock(&mut);
}
这应该确保线程获得其组所需的资源(忽略数组+模数的环绕)。当然,并不能真正保证他们醒来并继续他们正在做的其他事情的顺序。我也对这段代码表示怀疑:
if (meet_ord == MEET_LAST)
add_codeword(value, len);
因为看起来新组的第一个线程负责为该组执行 add_codeword 。那么,为什么另一个线程也在这样做呢?
关于c - 使用条件变量实现线程屏障会导致奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44599194/