C 线程-访问资源避免饥饿

C 线程-访问资源避免饥饿,c,linux,multithreading,C,Linux,Multithreading,我知道这不是一个“家庭作业帮助网站”,但我在过去的几天里疯了,因为我必须实现对资源的访问以避免饥饿,我不知道如何做到这一点。有人能帮我提供一些应用程序示例或文档吗?分配为:一个资源可由两种类型的进程使用:黑色和白色。当资源被白色进程使用时,它不能被黑色进程使用,反之亦然。实现对资源的访问,避免饥饿。这是生产者-消费者的情况吗?一般来说,访问共享资源(或互斥)是一个问题 如果有两个同一类的对象,则两个线程: 伪代码: loop if shared_resource is free

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

一般来说,访问共享资源(或互斥)是一个问题

如果有两个同一类的对象,则两个线程:

伪代码:

loop 
   if shared_resource is free
      lock shared_resource
      do something
      free shared_resource 
这是一个非常宽泛的概念

让我们做一些假设(为了讨论):
  • 我们的进程将是线程——而不是实际的软件进程,在您的任务中可能有一个重要的区别
  • 白色进程是读卡器
  • 黑人是作家
  • 我们的共同资源是特定的变量
互斥锁(): 互斥锁是一种排他锁,它有一个二进制状态,它要么被锁定,要么被解锁。您可以锁定、解锁或检查它是否已锁定

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

当您想要保护一个变量不被两个线程同时使用时,您可以为该变量创建一个互斥体,并写入每个线程,以便它在尝试使用该变量之前尝试锁定互斥体,并在使用完成后解锁该互斥体

这使得任何第一个线程都会锁定互斥锁和任何后续的线程块,直到第一个线程解锁互斥锁为止,基本上迫使所有这些线程排队并按顺序操作该特定变量

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

(RWL): 大多数读写锁的实现都将使用共享锁和独占锁,但它们公开了一种简单的使用方法:如果要读取,请获取“读取锁”,如果要写入,请获取“写入锁”

“读锁”不是独占的,它们允许多个读卡器在一个特定时间进行读取(无阻塞)

“写锁”是排他性的,在一个特定的时间只能有一个写入器进行写入(无阻塞)

饥饿:
  • 第一步:Readers/Writers Locks是当第一个(读)线程获取变量上的“读锁”时发生的事件,第二个(写)线程尝试获取“写锁”,但被阻止,直到所有读卡器完成读取
  • 第二步:在第一个线程完成读取之前,第三个(读取)线程抓取变量上的“读取锁”;这意味着第二个(写)线程必须等待第三个线程完成
重复第二步,直到达到饥饿状态

通过以下方式避免饥饿: seqlock由一个互斥锁和一些计数器实现。它始终允许读取,即使写入程序正在写入变量,但它为读取器提供了一种检查数据是否在读取期间写入的方法,如果是这样,则可能会损坏,因此读取器必须重新读取数据并再次检查一致性

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

写入程序使用互斥来获取独占访问,因此它们从不重叠操作

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

你的特殊情况: 如果黑色进程需要能够在它们之间共享资源,而白色进程需要能够在它们之间共享资源,但是白色进程不能与黑色进程共享资源,那么解决方案将不是RWL或Seqlock


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

您了解饥饿的症状是什么吗?只要您让我们知道这是家庭作业,并接受这样一个事实,即我们将尝试不直接向您提供解决方案,而是引导您走上正确的道路,帮助您了解基本知识,那么“家庭作业帮助网站”也是如此(或者是目前正在逃避你的事情)并让你为之工作。就read而言,饥饿是一个或多个线程无法进展的情况。死锁同样存在问题。