【发布时间】:2013-01-27 06:00:10
【问题描述】:
我正在尝试使用共享内存和信号量来实现管道(可能我还需要信号来完成我的实现)
我遇到了如何正确设置信号量的算法问题。
假设我已经为管道缓冲区分配了一块共享内存, 和一块用于管道信息的共享内存(例如管道中有多少字节等......)
- 我想创建互斥(一次只有一个读取器/写入器使用管道)
- 如果读者想从空管道中读取,我应该阻止他,直到作者写了一些东西
- 与 '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'个字节......
这意味着写入者在写入之前必须检查管道中有多少可用空间。这是一个问题——因为作者会在没有互斥的情况下触及关键部分(管道的信息)..
所以我想把这部分放在关键部分,但是 - 如果一个作家想要写作并且管道已满 - 我怎么能只让一个读者在里面,然后让作家写更多?
我有点糊涂了……
任何帮助将不胜感激,谢谢!
【问题讨论】:
-
SYSV 消息队列或 POSIX 消息队列适用于此类任务。它们是内核持久的,只需要发送和获取调用。
-
这看起来还不错。
-
@vonbrand 这不是很好(我认为),看看下一个场景:一个想要写 'n' 字节的作家检查管道中有多少字节,并且有空间多 2 个字节。因此作者将写入 2 个字节并完成(这就是管道的工作方式,不是吗?).. 现在:如果作者获得此信息,他可以写 2 个字节,然后控制权交给阅读器,阅读器读取'10 bytes',然后控制权返回给可以写入 12 个字节而不是 2 个字节的写入器……但他不知道
-
你不是“看有没有空间,有没有再写”,你要求空间(减少
free信号量,如果可以的话,你就等到有),然后写。看看greenteapress.com/semaphores,当然可以处理不是按 1 而是按任意数量递增/递减的信号量。 -
@vonbrand ,作为一个想要读取 2 个字节的读者,我需要检查是否有 2 个字节要读取.. 如果只有一个字节,那么我会读取一个字节和'我会走开(像管子一样).. 不是吗?我知道信号量不能增加/减少 1,但事实并非如此
标签: c signals pipe shared-memory semaphore