c - 使用共享内存和信号量实现管道

标签 c signals pipe shared-memory semaphore

我正在尝试使用共享内存和信号量来实现管道(可能我还需要信号来完成我的实现)

我遇到了如何正确设置信号量的算法问题。

假设我已经为管道缓冲区分配了一 block 共享内存, 以及一段用于存储管道信息的共享内存(例如管道中有多少字节等......)

  1. 我想创建互斥(一次只有一个读取器/写入器使用管道)
  2. 如果读者想从空管道中读取内容,我应该阻止他,直到作家写出一些内容
  3. 与“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/

相关文章:

c++ - 查找耗时

c++ - 接收信号时如何自动进行gdb核心转储

c - 在 c 中使用管道和 I\O 重定向的 Shell 实现

c - 如何在打开/写入功能中实现超时

winapi - Win32 : Determine whether stdout handle is char or wchar stream

c - FlexeLint 在 va_list 上抛出错误

c - '=': left operand must be l-value - Looking to use an Array within C Language

当串行设备的路径改变时,C 程序停止

Perl:是否可以撤消 SIG{INT} 捕获?

c++ - pthreads - 强制线程运行