在操作系統概念(Silberschatz,第9版)第3.4.1,作者提出了生產者 - 消費者問題,並給出了使用循環緩衝區(125頁,126)下面的實現。生產者 - 消費者實施中是否存在競爭條件?
//Shared variables
#define BUFFER SIZE 10
struct Item;
Item buffer[BUFFER SIZE];
int in = 0, out = 0;
//buffer is empty when in == out
//buffer is full when (in + 1) % BUFFER SIZE == out
//Producer
while (true)
{
Item next_produced = /*produce item here*/;
while (((in + 1) % BUFFER SIZE) == out) ; //do nothing
buffer[in] = next_produced;
in = (in + 1) % BUFFER SIZE;
}
//Consumer
while (true)
{
while (in == out) ; //do nothing
Item next_consumed = buffer[out];
out = (out + 1) % BUFFER SIZE;
//consume the item in next_consumed here
}
書中說:
一個問題這說明不解決關切 的情況這兩個生產者進程和消費者進程試圖 訪問共享緩衝區兼任。
我沒有看到的情況下生產者和消費者會同時訪問同一緩衝元素。
我的問題是:如果生產者和消費者兩個線程運行,是否有競爭條件或其他同步問題在此實現?
請詳細說明一下#2'編譯器可能會重新安排lines'。簡單地交換行會顯然產生不同的行爲,所以我猜你寧願意味着沿着「編譯器可能將其重新排列爲'{int temp = in; in =(in + 1)%BUFFER SIZE; buffer [temp] = next_produced;}'「。然而,如果'in'是一個超出邊界的索引(這可能導致例如拋出異常),則這種重寫將具有不同的UB。在原始代碼中,UB處的「in」將是無效的,在重寫時它將是有效的。 C標準真的允許這樣的重寫嗎? – dxiv
相當多的語言允許編譯器爲了優化而重新排列指令。只是谷歌的「C++編譯器重新排序指令優化」會給你一些信息。 –
@dxiv另外,看看https://en.wikipedia.org/wiki/Memory_ordering和https://en.wikipedia.org/wiki/Consistency_model – jyvet