很抱歉,如果我再次提出同样的问题,但想要验证!
我有两个进程P1和P2。
P1是作家(制片人) P2是读者(消费者)。
有一些共享内存或P1写入的文件,一旦P1写入,P2应该被通知读取。
现在根据我的理解,P1的伪代码应该是
Open shared file Create a named event("Writedone") to signal write for P2 process Do some processing on file Mutex.Lock() Write to File Mutex.Unlock() Signal named Event. CloseHandle on file
现在在P2
Open handle to Shared file Open handle to named event WaitForSingleEvent on named event("Writedone") Read from file CloseHandle on file
问题:
编辑:每次编写器在文件末尾写入10个字节,读者应该读取写入者写的最新10个字节。
答案 0 :(得分:1)
答案是:如果(且仅当)两个线程可以同时使用相同的共享资源,则必须进行锁定。关于您的具体实施的信息不足,但我的评论很少:
答案 1 :(得分:0)
你需要读者获得锁定 - 事件的使用是无可替代的。没有它,作家可以在读者代码中的任何一点开始写作。
答案 2 :(得分:0)
您绝对需要消费者锁定,以防止生产者在读者阅读之前附加到文件。想象一下这种情况:
Producer writes and signals
Consumer receives signal
Consumer opens the file
Producer fires again and writes another 10 bytes
Producer signals
Consumer reads the last 10 bytes
Consumer closes the file
接下来发生的事情取决于您的命名事件是手动重置还是自动重置。如果它是自动重置,那么消费者将看到第二个信号,然后返回并再次阅读相同的内容。如果它是手动重置,那么消费者将重置事件并错过生产者写的最后一件事。
请注意,即使使用锁定,如果制作人能够快速响应,您也会遇到竞争条件。也就是说,在Consumer能够读取第一条记录之前,Producer可能能够将第二条记录放入文件中。
这里看来你所拥有的是一个在文件中实现的FIFO队列,并且你依赖于消费者处理数据的能力比生产者可以创建它更快。如果你能保证那种行为,那么你没事。否则,消费者必须跟踪它上次读取的位置,以便它知道下一步应该读取的位置。
答案 3 :(得分:0)
如果作者可以随时开始写,您需要锁定读卡器中的互斥锁。确保互斥锁是一个命名的互斥锁,因此P2可以打开它。
如果您在两个进程中使用FileShare.ReadWrite打开文件,则可以将其保持打开状态。
在阅读器中,您可能需要先寻找您点击EOF的地方才能再次阅读。
如果您确定编写器总是附加并且您可以告诉记录结束的位置(例如,因为它们总是10个字节),并且您可以接受一个小延迟,并且编写器总是写完整记录,您可以执行这根本没有互斥和事件。使用FileShare.ReadWrite打开文件,在阅读器中,继续寻找同一个地方并尝试读取您的记录,如果不能,请暂停一下。如果你设法阅读整个记录,你就得到了一个。弄清楚你的位置并循环回去寻找那个地方并尝试再次阅读。这就是tail -f在Unix中的工作方式。
答案 4 :(得分:0)
除了常规同步功能外,您还可以使用Windows上的file change notification API等待文件更改。