Concurrency 锁/条件变量问题

Concurrency 锁/条件变量问题,concurrency,locks,Concurrency,Locks,在我编写的程序中,我有三个函数,为了简单起见,我们把它们叫做A,B和C。每个函数都需要访问资源X才能工作 限制是A和B不允许同时运行,必须适当同步。然而,C允许与A或B同时运行 这给我带来了一些问题 首先,我试着在A和B上加锁,所以当A被调用时,它会获得X的锁,然后释放它,和B一样。这样,A和B按顺序运行。然而,如果我以这种方式使用锁,C将无法与A或B同时运行 因此,我尝试使用条件变量,其中A必须等待B发出的信号,如果B正在运行,B必须等待A发出的信号,但这种相互依赖的调用似乎也不起作用 不知道

在我编写的程序中,我有三个函数,为了简单起见,我们把它们叫做A,B和C。每个函数都需要访问资源X才能工作

限制是A和B不允许同时运行,必须适当同步。然而,C允许与A或B同时运行

这给我带来了一些问题

首先,我试着在A和B上加锁,所以当A被调用时,它会获得X的锁,然后释放它,和B一样。这样,A和B按顺序运行。然而,如果我以这种方式使用锁,C将无法与A或B同时运行

因此,我尝试使用条件变量,其中A必须等待B发出的信号,如果B正在运行,B必须等待A发出的信号,但这种相互依赖的调用似乎也不起作用


不知道该怎么办

没有对语言的控制,只谈理论,似乎有一个简单的方法。如果X是持久性的,并且A、B和C可以通过接触X的方式被调用,那么A、B和C在访问X时应该传入它们的名称,比如说,通过一个名为D的方法。D的作用如下:

  • 接受调用方名称和参数
  • 如果调用方是C,则将参数传递给X
  • 如果调用方是A或B,请检查X上是否有锁
  • 如果没有锁,则将参数发送到X
  • 如果有锁,等待打开
所以基本上用D来包装X。您甚至可以进一步简化,让D接受一个锁定或非锁定参数,而不是名称。如果锁定,则检查lock并可能等待,如果未锁定,则传递参数


这种方法似乎过于简单,但我不太了解您的实际情况。我知道这个问题不久前也被问到了,所以我不知道您是否还需要帮助。

如果(并且仅当)从C到资源的访问不需要序列化,那么您不需要对C设置任何锁,但这是一种非常奇怪的情况(并发运行并不意味着它们可以同时访问共享资源)。请发布更多关于你想做什么以及你使用的操作系统/语言的详细信息。我正在mac上用C编写代码。这里的共享资源是一家银行的分行,功能a和B分别是取款和存款,C是转账。我不能同时从同一分行(即使在分行的不同账户上)进行取款和存款,但我可以在分行内同时进行转账,只要进行转账的账户与处理存款/取款的账户不同。这与保持分支机构的总余额不被破坏有关。因此,不要为转账设置任何锁(但您必须以某种方式将帐户锁定在较低的级别)。如何实现这一点取决于您使用的是什么(这是一个直接访问数据库的示例吗?您使用的是某种服务吗?)。就个人而言,我不会使用双重锁定,所以我会使用帐户级别锁定(对于a、B和C)扩展到A和B的任何帐户。因为这些操作来自人类用户,所以您可能会认为使用一种机制,如DB中常用的A/B与C的乐观锁,以及A和B的简单sw锁。因此,您的意思是只在帐户级别设置锁,而不在分支级别设置锁?我不知道你所说的“扩展到A和B的任何帐户”是什么意思,我的意思是:设置一个软件锁(关键部分)来序列化A和B,让C自由工作。因为您需要帐户级别的同步,所以我将使用类似乐观锁(在数据库或服务级别)的机制将a/B与C同步(并为a/B授予另一级别的安全性)。