线程 - 访问资源避免饥饿

时间:2013-11-28 08:58:47

标签: c linux multithreading

我知道这不是一个“家庭作业帮助网站”,但我在最后几天感到疯狂,因为我必须实现对资源的访问以避免饥饿,我无法弄清楚如何做到这一点。有人可以帮我提供一些应用程序示例或文档吗?赋值是:资源可以由两种类型的进程使用:黑色和白色。当白色进程使用资源时,黑色进程不能使用它,反之亦然。实现对资源的访问,避免饥饿。这是生产者 - 消费者案例吗?

2 个答案:

答案 0 :(得分:3)

让我们做一些假设(为了讨论):

  • 我们的流程将是线程 - 而不是实际的软件流程,这在您的任务中可能很重要。
  • 白色流程是读者。
  • 黑色进程是作家。
  • 我们的共同资源是特殊的变量。

互斥锁(mutex):

互斥锁是一种独占锁,它具有二进制状态,它被锁定或解锁。您可以锁定它,解锁它或检查它是否锁定。

线程可以使用互斥锁(互斥锁)互相锁定,就像进程可以使用信号量锁定对方一样。

如果要保护变量不被两个线程同时使用,则为该变量创建一个互斥锁并编写每个线程,以便它在尝试使用变量之前尝试锁定互斥锁并在它们之后解锁它完成。

这使得任何第一个线程锁定互斥锁和任何后续线程阻塞,直到第一个线程解锁互斥锁,基本上强制所有这些线程按顺序排列并对该特定变量进行操作。

当您只想读取变量而不更改其值时,这有点无效,因为读取相同内容的两个线程不会产生任何冲突或无效数据。但是,同时写两个线程可能会破坏数据。

Readers/Writers locks(RWL):

读者/写锁的大多数实现都将使用共享锁和独占锁,但是它们暴露了一种简单的使用方法:如果你想读取“读锁”,如果你想写一个“写锁” ”

“读锁定”不是排他性的,它们允许多个读者在特定时间阅读(不会阻塞)。

“写锁定”是独占的,只有一个作者可以在一个特定的时间写入(没有阻塞)。

饥饿:

  • 第一步:读取器/写入器锁定是第一个(读取)线程抓取变量“读取锁定”的事件,第二个(写入)尝试获取“写入锁定”但被阻止直到所有读取器完成读数。
  • 第二步:在第一个线程完成读取之前,第三个(读取)线程抓取变量的“读锁定”;这意味着第二个(写)线程必须等待第三个线程完成。

重复第二步直到实现饥饿。

使用Seqlock避免饥饿:

使用一个互斥锁和一些计数器实现seqlock。它总是允许读取,即使在写入器写入变量时它也会给读者提供一种检查数据是否在读取期间被写入的方法,如果是这样,它可能是腐败的,因此读者将不得不重新读取数据并再次检查一致性。

“读取和一致性检查”阶段在循环中运行,直到检查确认数据的一致性,此时读者可以继续执行其常规任务。

作者使用互斥锁获取独占访问权限,因此他们永远不会重叠他们的操作。

这适用于高读低写入情况。如果写作者太多,读者将不断循环重读数据。

您的具体情况:

如果黑色进程需要能够在它们之间共享资源,并且白色进程需要能够在它们之间共享资源,但白色进程无法与黑色进程共享资源,那么解决方案将不是RWL或顺序锁。

Seqlock算法的变体可能是您的解决方案。

答案 1 :(得分:0)

通常,它是访问共享资源(或互斥锁)的问题。

如果你有两个相同类的对象,那么两个线程:

伪码:

loop 
   if shared_resource is free
      lock shared_resource
      do something
      free shared_resource 

这是非常广泛的术语!