我正在尝试使用共享内存和信号量来实现管道(可能还需要信号,以完成我的实现)
我遇到了如何正确设置信号量的算法问题。
假设我已经为管道缓冲区分配了一段共享内存, 和管道信息的一段共享内存(例如管道中有多少字节等等)
我试图寻找答案,但即使看起来像是一种常见的练习,我也没有找到答案......
我知道一种称为“有界缓冲问题”或“消费者生产者问题”的解决方案 这是这样实现的:
有3个信号量: 互斥 - 初始化为1 完全 - 初始化为0 empty - 初始化为n(而n是数字,假设我在管道中有“字节”)
消费者代码:
wait(full)
wait(mutex)
remove a byte from the pipe
signal(mutex)
signal(empty)
制作人代码:
wait(empty)
wait(mutex)
add a byte to the pipe
signal(mutex)
signal(full)
此解决方案中的问题(用作我的问题的解决方案)是在给定时间内,只从管道读取一个字节,或写入其中。
在我的问题中 - 实现管道,我不确定写入器将写入多少字节。如果他想写'n'个字节,那么只有在管道中有一个位置时才会写它,如果没有,他会写的少于'n'个字节......
这意味着在写入之前,作者必须检查管道中有多少可用空间。这是一个问题 - 因为作者将触摸一个关键部分(管道的信息)而不互相排斥..
所以我想把这个部分放在关键部分,但是 - 如果一个作家想要写并且管道已满 - 我怎么能只让一个读者进入,然后让作者写更多?
我很困惑......
任何帮助将不胜感激,谢谢!
答案 0 :(得分:0)
没有必要拥有这么多互斥锁或锁定它们的时间。在单一的生产者/消费者场景中,生产者永远不需要担心减少自由空间(它是唯一可以消耗该空间的人),对于消费者来说也是如此。因此,您的伪代码应为:
<强>生产者强>
while (lock_and_get_free_space() < bytes_to_write)
wait()
unlock()
write(bytes_to_write)
lock_and_update_free_space()
<强>消费强>
while (lock_and_get_data() < bytes_to_read)
wait()
unlock()
read(bytes_to_read)
lock_and_update_free_space()