【问题标题】:Using Mutex and semaphore使用互斥量和信号量
【发布时间】:2016-08-30 19:58:14
【问题描述】:

我很困惑我应该在我的应用程序中使用互斥锁还是信号量,基本上我的应用程序是一个使用 C 和 Pthreads 编程的多线程服务器。在我的应用程序中,一个线程依赖于另一个线程,即一个线程需要等到另一个线程满足条件。早些时候我使用 While 循环来检查其他线程何时将条件设置为 true,但 While 循环不必要地消耗 CPU 周期,即 CPU 消耗高达 100%。

目前我开始在我的应用程序中使用互斥锁,如下所示:

pthread_mutex_lock(&t_data[rc].mutex);
pthread_mutex_unlock(&t_data[rc].mutex);

在一个线程中,我锁定了互斥体,当第二个线程中满足条件时,我在第二个线程中解锁它(我已经在一个结构中处理了这个做索引,在其中我保留了一个互斥体字段的其他项目,当新客户端建立连接时,每个线程都被分配一个索引)。使用它一切正常,服务器的 CPU 消耗已降至 2%。但我有一个问题。

正如互斥锁的定义所说,考虑如果有 10 个线程正在运行并且它们共享一个公共资源假设一些全局变量,所以当一个线程锁定一个互斥锁时,其他线程无法访问共享资源,直到锁定了该互斥锁的线程互斥锁释放它。我的应用程序也是如此。考虑我有 10 个活动线程,5 个线程将依次锁定互斥锁,其他 5 个线程将释放互斥锁。如果一个线程锁定了互斥锁,那么其他 4 个线程需要等待它被释放。所以在某个时间点,如果一个线程锁定了一个互斥体并且它没有被释放,那么可能会发生死锁情况,那么所有其他线程将继续等待。

请帮我摆脱这个问题。理论上它可能看起来很尴尬,但这是一个真实的案例场景。请在投反对票之前再次检查问题。

【问题讨论】:

  • 一个互斥锁一次只能被一个线程持有,持有它的线程必须释放它。您应该学习如何将互斥锁与条件变量和谓词结合使用。这是要理解的最重要的构建块,您可以使用这些部件构建几乎任何您想要/需要的东西。
  • 因为我创建了一个互斥体数组,如果我锁定一个互斥体,考虑 mutex_arr[0] 那么它会锁定所有其他线程对公共代码区域的访问吗?简而言之,创建单个互斥体或互斥体数组是否有所作为
  • '如果一个线程锁定了一个互斥体并且它没有被释放然后所有其他线程将继续等待'可能会发生死锁情况'这不是死锁,这是一个错误。
  • 没有更多细节,例如。 MCVE,我们不知道您的问题的确切性质。正如您所描述的那样,您的应用程序因滥用互斥锁而充满了 UB,您应该使用 condvars 或信号量。您的应用程序目前的形式似乎注定要失败,但无法确定,因为没有代码:(

标签: c multithreading mutex semaphore


【解决方案1】:

在您的情况下,请考虑使用条件变量。让 5 个线程在 condvar 上等待,如果线程完成,如果您希望另一个线程继续运行,则向 condvar 发出信号,或者调用广播让所有其他阻塞线程继续运行。查看这些 pthreads API:

pthread_cond_wait to wait on the condition
pthread_cond_signal  to signal one thread of the waiters
pthread_cond_broadcast  to signal all threads that are waiting

【讨论】:

  • 因为我创建了一个互斥体数组,如果我锁定一个互斥体,考虑 mutex_arr[0] 那么它会锁定所有其他线程对公共代码区域的访问吗?简而言之,创建单个互斥体或互斥体数组确实有所作为。
  • @Ramanujam 您应该使用单个互斥锁来锁定临界区,使用互斥锁数组什么都不锁。 :)
猜你喜欢
  • 2011-04-20
  • 2017-08-24
  • 1970-01-01
  • 2012-09-01
  • 2015-10-25
  • 2022-11-01
  • 2013-12-07
  • 2021-08-14
  • 1970-01-01
相关资源
最近更新 更多