系列同步問題:
經典同步問題一——生產者和消費者問題
經典同步問題二——哲學家進餐問題
經典同步問題三——讀者寫者問題
不懂得結構型訊號量的小夥伴可參考下面博文,之後再閱讀本博文,更易於理解
乙個或多個生產者產生資料並放在緩衝區中,每次乙個。
乙個或多個消費者從緩衝區取資料項並消費,每次乙個。
條件:1 在任意時間只能乙個生產者或消費者訪問緩衝區——互斥
2 保證生產者不能向滿緩衝區中放產品
3 保證消費者不能從空緩衝區中取產品
q:為什麼緩衝區要互斥?
a:舉例說明:環形緩衝區,用in指標指向將要放產品的緩衝區下標,out指標指向將要取出產品的緩衝區下標。對應一下put和take操作:
put
(a)take()
如果有兩個程序p1和p2,在p1將a寫入buffer[in]中後,in還未來得及改變的時候,p2又將b寫入buffer[in],則出錯。因此緩衝區需要互斥訪問。
不考慮條件的話,問題如下:
void
producer()
}void
consumer()
}
考慮實現互斥條件,只需設定訊號量s.value=1,並在緩衝區操作前加上wait(a),緩衝區操作後加入signal(a)。
semaphore s.value =1;
void
producer()
}void
consumer()
}
考慮實現緩衝區為空時不能取產品,則必須在至少乙個生產者實現put(a)操作後,才能執行take(a)操作。只需設定訊號量n.value=0,在put之後執行signal(n),在take之前執行wait(n)。此時n.value彷彿乙個計數器,記錄著緩衝區產品的個數,只要這個值大於零,消費者就可以消費,而且在消費者消費之前,n.value要減1,即take之前要先執行wait(n)。
這裡有兩個問題,為什麼signal(n)要放在signal(s)之後,為什麼wait(n)要放在wait(s)之前。
先說第乙個問題,為什麼signal(n)要放在signal(s)之後?
如果交換signal(n)和signal(s)的位置,先執行signal(n),後執行signal(s),則此時signal(n)是在臨界區內執行。此時可能出現以下情況:如果乙個消費者因執行wait(n)而正在等待,則此時執行signal(n)將會被喚醒。而此時生產者還沒有從臨界區出來,則消費者會因為執行wait(s)而繼續被阻塞。由此可見,交換signal(s)和signal(n)不會出錯,但是從優化角度來說,signal(s)在前更好。
再說第二個問題,為什麼wait(s)要放在wait(n)之後?
如果交換wait(s)和wait(n)的位置,先執行wait(s),後執行wait(n),則此時我們把wait(n)放入了臨界區中。我們知道wait操作在某種情況下會導致程序進入等待狀態。現在假設我們在初始情況下先執行consumer(),執行wait(s)時,由於s.value的初值是1,則可以進入臨界區,再執行wait(n)時,由於n.value=0,則會導致程序阻塞。而我們發現,能夠喚醒wait(n)的signal(n)操作,必須在使用臨界區之後才能執行,那麼這種情況下,臨界區被阻塞,生產者永遠不可能進入臨界區,也就永遠不可能執行signal(n),阻塞將一直存在,即產生了死鎖。這種次序的交換會引起錯誤。
semaphore s.value =1;
semaphore n.value =0;
void
producer()
}void
consumer()
}
考慮實現緩衝區滿時不能再放入產品。可以設定乙個訊號量e.value=max,每向緩衝區放1個產品,e.value減1,當值減為0,說明不能再放入產品。也就是要在put前面加上wait(e)操作。同理,每消費乙個產品,e.value加1。即在take之後加上signal(e)操作。
這裡同樣存在上文所說的兩個問題。即signal(e)為什麼要在signal(s)之後,wait(e)為什麼要在wait(s)之前。原因也如上文所述。同樣交換signal不會出錯,交換wait會產生死鎖。
semaphore e.value = max;
semaphore s.value =1;
semaphore n.value =0;
void
producer()
}void
consumer()
}
程序間同步互斥經典問題 一 生產者 消費者問題
生產者 消費者問題,也叫做快取繫結問題 bounded buffer 是乙個多程序同步問題。要避免多個生產商競爭乙個空位的情況。要避免生產商和消費者同時睡覺,造成死鎖 要避免多個消費者競爭同一段資料的情況 首先考慮生產商,在多個生產商和多個消費者同時執行的情況下 2.每乙個生產商在執行操作前申請互斥...
6 1 生產者 消費者問題
在多執行緒程式中,執行緒之間通常存在分工。在一種常見模式中,一些執行緒是生產者,一些是消費者。需要強制執行幾個同步約束才能使此系統正常工作 在緩衝區中新增或刪除專案時,緩衝區處於不一致狀態。因此,執行緒必須具有對緩衝區的獨佔訪問許可權。如果消費者執行緒在緩衝區為空時到達,則會阻塞,直到生產者新增新專...
5 12 生產者和消費者
一 生產者和消費者之間的關係 1 生產者將生產出來的資訊不斷存入乙個區域內,消費者將資訊從該區域內不斷讀取出來 生產者錄入資訊 消費者讀取資訊 例 電影票 public class movie public void setname string name public string getinfo...