gpt4 book ai didi

c - pthread_cond_wait 是否锁定互斥量和虚假唤醒

转载 作者:太空宇宙 更新时间:2023-11-04 00:43:23 25 4
gpt4 key购买 nike

长话短说

我有一个作业需要实现线程同步。在实现过程中,我担心 pthread_cond_wait() 是否也锁定了互斥锁,如果它被虚假唤醒,而不仅仅是成功唤醒。

任务

该任务是一个工作人员/交付问题,其中有工作线程和管理线程为工作人员提供订单。为此,有一个订单列表,工作人员从中获取订单,管理线程存放订单。订单列表是共享对象,需要同步。

到目前为止我的解决方案

我想到了这个问题,我需要一个列表监视器来保护它免受空的访问或当它已满时的存款。

void deposit_order(order_list* ol, order* o){
pthread_mutex_lock(&(ol->mut_order_access));
while(get_count(ol) >= MAX_ORDERS) {
pthread_cond_wait(&(ol->cond_not_full), &(ol->mut_order_access));
}

ol->orders[ol->head] = o;
ol->head = (ol->head+1)%MAX_ORDERS;
ol->count++;

pthread_cond_signal(&(ol->cond_not_empty));
pthread_mutex_unlock(&(ol->mut_order_access));
}

order* get_order(order_list* ol) {
pthread_mutex_lock(&(ol->mut_order_access));
while(get_count(ol) <= 0) {
pthread_cond_wait(&(ol->cond_not_empty), &(ol->mut_order_access));
}
order* o;

o = ol->orders[ol->tail];
ol->tail = (ol->tail+1)%MAX_ORDERS;
ol->count--;

pthread_cond_signal(&(ol->cond_not_full));
pthread_mutex_unlock(&(ol->mut_order_access));
return o;
}

我认为结构包含什么并不重要,因为主题是如何同步访问。显然,order_list 结构包含一个 mutex 和两个向另一个线程发送信号的条件变量。因此,如果一个工作人员从列表中删除一个任务,它会向管理线程发出“不为空”的信号,以便它可以存放一个额外的订单。如果管理层存入一个订单,则向工作线程发出“不为空”的信号,这样一个线程就可以从列表中删除一个订单。

我的担忧

到目前为止一切顺利,但现在我认为上述解决方案可能很关键,这就是“虚假唤醒”。来自 this thread我了解到,如果相应的互斥锁 mut_order_access 被另一个线程锁定,则线程无法虚假唤醒。但是,如果列表中只有一个订单,因此 get_count(ol) >= MAX_ORDERS 未满足并且线程虚假地从等待中唤醒,检查条件并将其标记为未满足怎么办true 并跳出循环。然后另一个线程收到信号并在前一个线程已经在临界区后正常唤醒并锁定互斥锁。因此,现在两个线程都将处于失败的关键区域。

问题

所以只有当一个线程在虚假唤醒时没有锁定互斥量时才会发生上述情况,那么它是否在虚假唤醒时锁定了互斥量?

最佳答案

您对虚假唤醒条件的理解似乎不正确。虚假唤醒与互斥量是否被另一个线程锁定无关。除非您有编程错误(破坏这些函数的契约、一般内存损坏或其他未定义的行为等),否则 pthread_cond_wait 永远不会在调用线程持有(锁定)互斥锁的情况下返回。在虚假唤醒的情况下,它仍然无法返回,直到重新获取互斥锁。即使在使用 pthread_cancel 取消服务员的情况下,取消清理处理程序也无法开始运行,直到重新获取互斥体。

关于c - pthread_cond_wait 是否锁定互斥量和虚假唤醒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56707687/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com