如果我需要在锁定互斥锁后解锁它,我该如何返回一个值?

Posted

技术标签:

【中文标题】如果我需要在锁定互斥锁后解锁它,我该如何返回一个值?【英文标题】:How do I return a value if I need to unlock a mutex after locking it? 【发布时间】:2021-11-25 09:48:54 【问题描述】:

我正在用 C 语言编写一个程序,我需要多个线程来访问队列中的元素。显然,我需要有某种锁定,这样多个线程就不会试图同时篡改队列中的同一个元素。

所以我所做的是围绕我的队列创建一个包装器,供每个线程调用,而不是直接访问我的队列。

我遇到麻烦的地方是我的 dequeue 命令。我的出队命令应该工作的方式是我需要返回存储在队列头部的任何数据 - 但是,由于我试图使我的队列原子,我必须用锁(pthread_mutex_lock/unlock() )。如果我需要将该数据返回给调用函数,我怎样才能在仍然能够解锁我的锁的同时这样做?

int atomic_dequeue(Queue q) 
  pthread_mutex_lock(&lock);
  return dequeue(q);
  pthread_mutex_unlock(&lock);

【问题讨论】:

将结果保存到变量中,解锁后返回变量? dequeue(q) 的返回值是否仅在并发上下文中有意义(取决于竞争条件)?在这种情况下,我建议提供atomic_dequeueQueue q 一个回调,用于在释放互斥锁之前在锁定的上下文中处理这个返回值。 @kaylum 当下一个线程在第一个线程返回 rv 之前分配从 dequeue 返回的值时会发生什么?在我的应用程序中,可能有数百个线程将等待解锁并更改返回变量的值。 【参考方案1】:

将值存储在变量中。

int atomic_dequeue(Queue q) 
  pthread_mutex_lock(&lock);
  int rv = dequeue(q);
  pthread_mutex_unlock(&lock);
  return rv;

【讨论】:

如果下一个线程在第一个线程可以返回 rv 之前分配从 dequeue 返回的值,会发生什么?在我的应用程序中,可能有数百个线程将等待解锁并更改返回变量的值。 每个线程都有自己的栈,所以每个线程都有自己的rv

以上是关于如果我需要在锁定互斥锁后解锁它,我该如何返回一个值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在启动应用程序时锁定方向并在导航到 Viewcontroller 时解锁它

解锁后无法在 JavaCard 中列出或安装 CAP 文件。为啥?以及如何解决?

PostgreSQL 锁定行无限期

Android studio,每天在给定时间后解锁活动

通知条件变量并解锁关联互斥锁后的“数据竞争”(不是真的)

等到另一个进程锁定然后解锁 Win32 互斥锁