【发布时间】:2016-09-20 17:47:08
【问题描述】:
原则上我想要的很简单。
两个可执行文件./read 和./write 分别从一个资源(比如说一个文件)读取和写入。使用flock(2) 可以轻松防止在任意时间任意调用./read 和./write 之间的竞争条件。
要求./read 的每次调用都包含来自先前调用的资源快照,如果当前资源与快照匹配,./read 应等待(休眠)直到调用 ./write 更改资源。
据我所知,每个程序的程序流程应该是这样的:
//read.c
obtain mutex0
read resource
is resource same as our snapshot?
release mutex0 [1]
sleep until ./write says to wake up [2]
obtain mutex0
read resource
do something with resource
release mutex0
//write.c
obtain mutex0
change resource in some way
tell any sleeping ./read's to wake up
release mutex0
这种方法的主要问题是标记为[1] 和[2] 的行之间存在明显的延迟。这意味着./read 可以在[1] 处释放mutex0,可以完成对./write 的整个调用,然后执行[2],但将无限期停止,因为./write 已经尝试唤醒任何休眠的@ 987654339@s 之前。
除了使用整个独立的成熟服务器进程之外,有没有简单的方法可以做我想做的事?此外,对于那些好奇的人,我想为 CGI 中的应用程序这样做。
【问题讨论】:
-
你可以使用信号量而不是互斥体。
-
在我看来你想要进程间通信。我建议阅读 linux 的命名管道或 ZeroMQ 而不是您的临时方案。
-
你们的 cmets 都没有解决我指出的竞争条件。我知道信号量,我知道 IPC。
-
如果读取释放信号量,然后在读取到达下一行之前写入信号量,信号量将为 1,读取将继续。有不同的问题吗?
-
首先,如果我们简单地将上面的
mutex0替换为信号量,您所说的就没有意义。我认为您的意思是使用第二个信号量,所以我们称它为semaphore0和semaphore1,其中semaphore0替换上面的mutex0,而semaphore1信号read。仍然不起作用,因为write不知道增加多少次semaphore1,因为任何数量的reads 都可以休眠,如果您仍然认为自己是对的,请随时发布更具体的你正确的例子。
标签: c linux asynchronous synchronization glibc