这似乎是它应该是一个众所周知的问题,但我一直没能找到一个很好的解决方案,这(既不是来自我的大脑也不是互联网)。多个请求单个响应同步
首先,让我们一个很简单的例子:
mutex request <-- init to 0
mutex response <-- init to 0
Service thread (Guy S):
while not finished
wait(request)
do stuff
signal(response)
Someone requestion service (Guy U):
signal(request)
wait(response)
do stuff with results
到目前为止好。 U
(用户)信号S
(服务),并等待其响应。一切都很好。
现在想象一下,如果有很多用户,请求相同的服务。现在,服务的性质使得结果随时间变化(更确切地说周期性)。因此,如果10个用户要求的服务更多或在同一时间少,该服务可以安全地只运行一次。
,想到的第一件事情是这样的:
Guy S:
while not finished
wait(request)
do stuff
trywait(request)
broadcast(response)
Guy U:
signal(request)
wait(response)
do stuff with results
的不同,这里是这样的,首先S
trywait
S于请求时,它有效地设置为0,因此,如果很多人已经暗示它,只有一个请求会通过。当然,互斥量的上限为1,所以所有额外的信号累积到1,这将被trywait
删除。第二个变化是,S
将broadcast
的响应,这样所有的U
s就可以解锁。
看起来不错乍一看,但有一个问题吧。试想一下,处决的顺序如下:
Guy S: Guy U1: Guy U2:
wait(request)
signal(request)
working
signal(request)
wait(response)
working
trywait(request)
broadcast(response)
wait(response)
working
(loop)
如果你仔细观察,U2
被阻止,除非有人再次发送一个请求(上帝知道将来时)。很坏。
即使单个用户,这可能发生:
Guy S: Guy U:
wait(request)
signal(request)
working
trywait(request)
broadcast(response)
wait(response)
(loop)
谁能想出了一个好主意,或直接我一个已知的算法?
附加信息:
S
只是定期有新的数据提供,而是基于应用程序,用户可以决定得到零星的数据(通过请求),而不是周期性的。如果用户请求太快,我会让他等待下一段时间,所以这不是问题。- 我有机会,以飨读者 - 写锁,条件变量,信号灯和互斥。读者作家看起来很有希望获得响应锁定,但仍不清楚所有用户何时通过了他们的
wait(response)
部分。
'如果东西需要重做'的部分已经在那里。为简单起见,我已将其删除。问题是,考虑两个用户:信号(请求)和服务唤醒,做一些东西和信号(响应)。有了这个信号,只有一个用户会醒来,另一个用户会挨饿。我可以使用信号量而不是互斥量,然后这个代码(作为我的原始代码)都可以工作,除了现实中“需要重做的东西”并不那么清楚(在我的应用程序中) – Shahbaz 2012-04-05 21:48:18
我的目标是获得类似这个:“如果在服务一个请求的过程中,另一个请求到来,那么最后两个都会发出信号,因为它们两个都会得到相同的结果,如果不是,每当下一个请求服务时它都会服务。”虽然我说这项任务本质上是周期性的,但这并不完全正确。我有两种类型的服务,其中一种是定期的,我可以很容易地确定“是否需要重做”。另一个是用户的扩展,具有我无法预测的任何功能。 – Shahbaz 2012-04-05 21:50:20
@Shahbaz:我假设信号量;我的错。 (显然)你比我更了解上下文,但是如果另一个消费者没有完成他的请求(而不是刚刚完成),结果是不同的,并且没有其他标准来确定结果,那么似乎有点偏离。例如,如果服务记录了最后一次请求处理的时间,并且在某个窗口内出现的任何新请求获得了相同的结果,将很容易实现。 – 2012-04-06 00:52:27