关于该主题的帖子和答案一团糟,但似乎没有一个模型可以很好地模拟我的问题。在四处搜寻并搜索stackoverflow之后,我不太清楚我的问题的答案。
我有两个线程,一个主线程和一个从属线程。从属服务器需要先等待主服务器,然后才能继续通过特定点,因此我已经创建了一个互斥锁作为全局变量:

pthread_mutex_t lock;
然后在对主线程进行初始化的过程中,很久之前,从属线程才有机会访问它,我将其锁定:
在主线程中初始化:
pthread_mutex_lock(&lock)
然后在奴隶中,当它等待主人的时候,我这样做:
奴隶必须在这里等待:
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
同时,回到主节点时,我有时间释放被阻塞的从节点:
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
(注意:主机的锁定/解锁顺序相反。)
根据对互斥锁的了解,我认为从属设备将锁定锁,并卡在那里等待主设备将其解锁,然后立即将其再次锁定。就时间而言,从站需要很长时间(保证)才能再次回到这里,因此主站将有很多时间来重新锁定它。同样,主服务器不会再回到这里了,我们也不必担心主服务器或从服务器将另一方击败这些检查点。
当它没有按预期工作时,我扔了一些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);
现在这是我看到的输出:
从属线程启动锁定序列
...然后从站被阻止时经过了一段时间(几秒钟),最后出现了:
主线程启动锁定序列
主线程内部锁定序列
主线程已完成锁定序列
同时,奴隶没有任何进一步的进步,奴隶永远被封锁。我本以为他会阻止主人重新锁定,并且应该吐出他的指纹,表明他已经前进了。此输出清楚地表明,被阻止的从属即使有耐心等待轮到他,也没有机会锁定互斥锁。
那我对互斥锁和锁定/解锁缺少什么呢?
-gt-

最佳答案

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

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

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

从站等待标志:
pthread_mutex_lock(&lock);
while (!flag)
    pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);

当主机要释放从机时,它设置标志并用信号通知条件变量:
pthread_mutex_lock(&lock);
flag = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);

(请注意,互斥体在pthread_cond_wait()中被阻止时不会被保留)。

07-24 09:46
查看更多