gpt4 book ai didi

条件变量和 mutex_unlock

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

代码:

void *inc_func(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&count_threshold_cv);
sleep(1);
pthread_mutex_unlock(&mutex);
}
void *watch(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&count_threshold_cv,&mutex);
sleep(1);
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t id[2];
pthread_create(&id[0],NULL,watch,NULL);
pthread_create(&id[1],NULL,inc_func,NULL);
int i;
for(i=0;i<2;i++)
pthread_join(id[i],NULL);
}

现在我们有一个 mutex_unlock 函数要在每个线程中执行。和一个锁定的互斥量。为什么这不会导致未定义的行为。由于两个线程都尝试解锁同一个互斥锁,这导致一个线程试图解锁一个已经解锁的互斥锁。

编辑:pthread_cond_wait 释放 mutex 供第二个线程使用。现在考虑第二个线程执行 pthread_cond_signal,这导致第一个线程重新获取 mutex。现在我们有两个具有相同 mutex 锁的线程,因为它们都没有执行 mutex_unlock 因为“ sleep ”功能。我的理解有误吗?

最佳答案

  • pthread_mutex_lock() 如果要锁定的互斥锁已经锁定,则阻塞。如果互斥锁被解锁,它会返回。

  • pthread_cond_wait() 在开始等待时解锁互斥锁,并在返回前锁定。如果有问题的互斥量仍处于锁定状态,则返回可能会延迟。然后返回将被延迟,直到互斥量被解锁。

将以上内容放在一起并将其应用到您展示的代码中,您会发现每个线程函数都很好地以锁定开始,然后是解锁(依此类推),所以一切都很好。

引用示例代码:pthread_cond_wait()inc_func() 调用了 pthread_mutex_unlock() 时返回。


要成功处理示例代码描述的场景,您需要考虑两种特殊情况

  1. 信号先到的情况
  2. 案例"spurious wake-ups" ,即 pthread_cond_wait() 在未收到信号的情况下返回。

要处理这两种情况,每个条件都应该有一个监视变量。

pthread_mutex_t mutex = ...
pthread_cond_t count_threshold_cv = ...

int signalled = 0;

void *inc_func(void *arg)
{
pthread_mutex_lock(&mutex);

pthread_cond_signal(&count_threshold_cv);
signalled = 1;

pthread_mutex_unlock(&mutex);
}

void *watch(void *arg)
{
pthread_mutex_lock(&mutex);

while (0 == signalled)
{
pthread_cond_wait(&count_threshold_cv,&mutex);
}

pthread_mutex_unlock(&mutex);
}

int main(void)
{
pthread_t id[2];
pthread_create(&id[0],NULL,watch,NULL);
pthread_create(&id[1],NULL,inc_func,NULL);
int i;
for(i=0;i<2;i++)
pthread_join(id[i],NULL);
}

关于条件变量和 mutex_unlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29320565/

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