winapi - 在 Windows 中,两个进程单个生产者/单个用户 什么是更好的互斥,事件或者信号量

  显示原文与译文双语对照的内容
0 0

我可以以使用这两种基本方法来使它工作,但是从性能角度来看,这个方案更适合。

我只需要同步两个进程。 总是有两个,没有更多,也没有更少。 一个写入内存映射文件,而另一个读取的是生产者/使用者时尚。 我关心性能,并且考虑到场景的简单性,我想我可以以使用轻量级,但是我不知道。

时间:原作者:1个回答

0 0

第一点:它们都是内核对象,所以它们都涉及来自用户模式到内核模式的switch 。 它本身就会增加足够的开销,你不可以能注意到它们之间的速度或者者任何类似的方法。 因这里,哪一个更优秀将取决于如何在共享内存区域中构造数据,以及如何使用它。

让我们从什么可能是最简单的情况开始: 共享内存区域形成了瓶颈。 消费者没有阅读的时间,生产者将会写作,反之亦然。 至少最初,这似乎是一个例子,我们可以使用一个互斥。 生成器等待互斥体,写入数据,释放互斥锁。 使用者等待互斥体,读取数据,释放互斥锁。 这一直持续到完成一切。

然而,尽管这样做可以防止生产者和消费者同时使用共享区域,但它并不能够保证正确的操作,因此不能保证正确的运行。 例如:生产者写一个充满信息的缓冲区,然后释放互斥锁。 然后它再次等待互斥,因这里当读者能够写更多的数据时,就不能保证消费者是下一个。 生产者可能立即返回,并将更多数据写入到,这样消费者就不会看到之前的数据。

防止这种情况的一种方法是使用几个事件: 从生产者到消费者说,有数据等待读取,另一个来自消费者的数据被读取。 在这种情况下,生产者等待它的事件,使用者只会在读取数据时设置它。 然后生成器写入一些数据,并信号消费者的事件,说明某些数据已经经准备好了。 消费者读取数据,然后向生产者发出信号,这样循环就可以继续。

只要你只有一个生产者和单个消费者,将整个数据视为一个单独的数据,那就足够了。 然而,这不能导致问题。 例如,我们考虑一个web服务器前端作为生产者和后端作为消费者( 以及一些将结果传递回web服务器的独立机制) 。 如果缓冲区足够容纳一个请求,生产者可以能需要缓冲多个请求,因为消费者处理一个。 每次消费者准备处理请求时,生产者必须停止它正在做的事情,复制请求。

不过,单独进程的基本要点是让每个进程尽可以能多地进行它自己的计划。 为此,我们可以在共享缓冲区中为许多请求腾出空间。 在任何给定时间,这些插槽的数量将完全为( 或者,从另一个方向看,一些数字是自由的) 。 对于这种情况,我们只需要一个计数信号来跟踪那些插槽。 生产者可以写任何时间,至少一个插槽是免费的。 消费者可以在任何时候阅读至少一个插槽被填充。

底线:选择与速度无关。 关于数据和进程对它的访问和处理的方式。 假设它真的像你描述的那么简单,这对事件可以能是最简单的机制。

原作者:
...