2013-02-12 124 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