gpt4 book ai didi

c++ - 为什么这个互斥代码没有按预期工作?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:39:20 24 4
gpt4 key购买 nike

关于这个主题有很多帖子和答案,但似乎没有一个能完全模拟我的问题。在谷歌搜索和搜索 stackoverflow 后,我不太明白我的问题的答案。

我有两个线程,一个主线程和一个从线程。 slave 在经过某个点之前需要等待 master,所以我创建了一个互斥量作为全局变量:

pthread_mutex_t lock;

然后在主线程的初始化中,在从线程有机会访问它之前很久,我就锁定了它:

在主线程中初始化:

pthread_mutex_lock(&lock)

然后在奴隶中,当它等待主人的时候我这样做:

奴隶必须在这里等待:

pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);

同时,回到 master 中,我有这个时间来“释放”被阻塞等待的 slave:

pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);

(注:加锁/解锁的顺序与master相反)

根据我对互斥锁的理解,我认为从机会撞到锁,并卡在那里等待解锁它的主人,然后立即再次锁定它。就时间而言,奴隶将需要很长时间(保证)再次回到这里,因此主人将有很多时间重新锁定它。同样,master 暂时不会再回到这里,我们也不必担心 master 或 slave 会抢先回到这些检查点。

当它没有按预期工作时,我输入了一些 printf 以确认主人解锁,然后在奴隶解锁之前重新锁定互斥量。我的理解是,奴隶在主人到达那里进行解锁和(重新)锁定之前很久就已经请求锁定,并且无论主人解锁和(重新)锁定之间的时间有多短,奴隶仍然应该能够锁定互斥体,因为他已经“排队”等待了。

但是,我看到发生的情况是主人解锁了互斥锁,然后立即重新锁定它,即使奴隶已经耐心地等待他锁定它的机会。

这是带有 printf 的代码和生成的输出:

奴隶:

printf("slave thread starting lock sequence\n");fflush(stdout);
pthread_mutex_lock(&lock);
printf("slave thread intra lock sequence\n");fflush(stdout);
pthread_mutex_unlock(&lock);
printf("slave thread completed lock sequence\n");fflush(stdout);

大师:

printf("master thread starting lock sequence\n");fflush(stdout);
pthread_mutex_unlock(&lock);
printf("master thread intra lock sequence\n");fflush(stdout);
pthread_mutex_lock(&lock);
printf("master thread completed lock sequence\n");fflush(stdout);

现在这是我看到的输出:

从线程启动锁序列

...然后一段时间过去了(几秒钟),而从站被阻塞,最后出现:

主线程启动锁序列

主线程内锁序列

主线程完成锁序列

与此同时,slave 没有进一步的进展,永远处于阻塞状态。我本以为他会阻止主人重新锁定并且应该吐出他的 printf 表明他已经向前移动了。此输出清楚地表明被阻止的从属没有机会锁定互斥量,即使他耐心地排队等待轮到他。

那么关于互斥量和锁定/解锁,我缺少什么?

-gt-

最佳答案

如对您的问题的评论中所述,pthreads 互斥体不能保证公平。

这项工作的正确工具是共享标志变量,由互斥锁保护并等待使用条件变量:

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int flag = 0;

slave等待标志:

pthread_mutex_lock(&lock);
while (!flag)
pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);

当master要释放slave时,设置flag并向条件变量发信号:

pthread_mutex_lock(&lock);
flag = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);

(请注意,当在 pthread_cond_wait() 中阻塞时,互斥体不会保持)。

关于c++ - 为什么这个互斥代码没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54994086/

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