我正在尝试使用共享内存和信号量来实现管道(可能我还需要信号来完成我的实现)
我遇到了如何正确设置信号量的算法问题。
假设我已经为管道缓冲区分配了一 block 共享内存, 以及一段用于存储管道信息的共享内存(例如管道中有多少字节等......)
- 我想创建互斥(一次只有一个读取器/写入器使用管道)
- 如果读者想从空管道中读取内容,我应该阻止他,直到作家写出一些内容
- 与“2”相同,但写入到完整的管道
我试图寻找答案,但没有找到任何答案,尽管这似乎是一个常见的练习......
我知道一个名为“有限缓冲区问题”或“消费者生产者问题”的解决方案 其实现如下:
有 3 个信号量: 互斥量 - 初始化为 1 full - 初始化为0 空 - 初始化为 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'个字节......
这意味着编写者在写入之前必须检查管道中有多少可用空间。这是一个问题 - 因为编写者将在没有互斥的情况下触及关键部分(管道的信息)..
所以我考虑把这部分放在关键部分中,但是 - 如果一个作家想要写并且管道已满 - 我怎样才能只让一个读者进入,然后让作家写更多内容?
我很困惑......
任何帮助将不胜感激,谢谢!
最佳答案
没有必要有这么多的互斥体或将它们锁定那么长的时间。在单一生产者/消费者场景中,生产者永远不需要担心可用空间减少(它是唯一可以用完该空间的空间),对于消费者来说也是如此。因此你的伪代码应该是:
制作人
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()
关于c - 使用共享内存和信号量实现管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14823922/