2013-02-12 79 views
0

我试图使用共享内存和信号灯来实现管道(也可能是我需要的信号也完成我的实现)使用共享内存和信号量实现管

我遇到的问题,算法如何设置信号量的权利。

可以说,我已经分配了一块管道缓冲, 和管道的信息一块共享内存共享内存(比如多少字节中有管,等...)

  1. 我想(使用管道一次只有一个读/写器)来创建互斥
  2. 如果读者想从空管阅读,我应该阻止他,直到一个作家写的东西
  3. 同样的事情,像'2',但是写给全管的作者

我试图寻找一个答案,但我没有找到任何即使它看起来像一个普通的运动...

我知道一个叫“界缓冲区的问题”或“消费生产者解决方案问题” 这是这样实现的:

有3个信号灯: 互斥 - 初始化到1 全 - 初始化为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'个字节的数据......

这意味着作者在写入之前必须检查管道中有多少可用空间。这是一个问题 - 因为作家将触摸一个关键部分(管道的信息),而不会互相排斥。

所以我想过把这部分放在关键部分内,但是 - 如果作者想写和管道已经满了 - 我怎么能让里面只有一个读者,然后让作者写更多?

我有困惑...

任何帮助将不胜感激,谢谢!

+1

SYSV消息队列或POSIX消息队列都是为了这样的任务。它们是内核持久化的,只需要发送和获取调用。 – 2013-02-12 01:20:34

+0

这看起来很好。 – vonbrand 2013-02-12 01:52:48

+0

@vonbrand这不好,因为它是(我认为),看看下一个场景: 想写'n'个字节的作者检查管道中有多少字节,并且还有2个字节的空间。所以编写者会写2个字节并完成(这就是管道工作的方式不是吗?)。 现在:如果一个作者得到这个信息,他可以写2个字节,然后控制权交给读者,谁读了'10字节',并且控制权返回到可以写入12字节而不是2字节的作者......但他不知道 – hudac 2013-02-12 09:33:10

回答

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() 
+1

这会导致死锁是'bytes_to_write'> ='free_space' &&'bytes_to_read'> ='n' - 'free_space',例如。 n == 2,'free_space' = 1,'bytes_to_write' == 2,'bytes_to_read' == 2。另外你似乎在等待互斥体,这会保证给你造成死锁。 – wich 2013-02-12 01:35:36

+0

@wich缓冲系统的设计应该能够读写w.r.t的数据。缓冲区大小。伪代码中的“等待”通常意味着“释放和等待”;例如查看[pthread_cond_wait](http://linux.die.net/man/3/pthread_cond_wait) – congusbongus 2013-02-12 01:53:23

+0

的行为_you读取/写入相当数量的数据w.r.t.缓冲区大小_这没有任何意义,一次读取或写入n个字节是理智的。 – wich 2013-02-12 07:23:38