單生產者 多消費者模型中遇到的問題

2021-09-07 14:11:47 字數 3383 閱讀 7022

近期使用單生產者-多消費者模型是遇到乙個問題,曾經既然都沒有想到過。生產者執行緒的**例如以下。基本功能就是接收到乙個連線之後建立乙個socket物件並放到list中等待處理。

void datamanager::internalstart() 

server_socket_->setsoblocking(true);

if (!server_socket_->listen())

socket *socket = null;

while (!stop_)

}}

多個消費者執行緒的的**例如以下,基本功能是從list中取得乙個socket物件進行處理。

void datamanager::workentry() 

if (stop_)

break;

socket = socket_list_.front();

socket_list_.pop_front();

}bool success = false;do}

} while (success);

delete socket;

socket = null;

}}

執行過程中進場出現段錯誤,都是在12行(socket = socket_list_.front())。使用gdb除錯發現socket_list_

的size為0

增加以下的

log進行除錯

@@ -115,6 +115,7 @@ voiddatamanager::internalstart()                                  

}@@ -129,11 +130,14 @@ voiddatamanager::workentry()

if (stop_)

break;

+ log(info) << "3: size: " << socket_list_.size();

socket = socket_list_.front();

socket_list_.pop_front();

+ log(info) << "4: size:" << socket_list_.size();

列印的log例如以下:

i0809 02:35:45.269896 17305datamanager.cc:114] recieved connection fd: 10.237.92.30:37220

i0809 02:35:45.269902 17305datamanager.cc:118] 1: size: 1

i0809 02:35:45.269928 17310datamanager.cc:133] 2: size: 1

i0809 02:35:45.269935 17310datamanager.cc:137] 3: size: 1

i0809 02:35:45.269937 17310datamanager.cc:140] 4: size: 0

………i0809 02:35:45.271636 17305 datamanager.cc:114]recieved connection fd: 10.237.92.30:37224

i0809 02:35:45.271644 17305datamanager.cc:118] 1: size: 1

i0809 02:35:45.271663 17310datamanager.cc:137] 3: size: 1

i0809 02:35:45.271670 17310datamanager.cc:140] 4: size: 0

i0809 02:35:45.271739 17309 datamanager.cc:133]2: size: 0

i0809 02:35:45.271750 17309datamanager.cc:137] 3: size: 0

a)        正常的log順序

正常的log順序應該是,add乙個socket之後得到,有乙個消費者執行緒被signal喚醒並處理這個socket。

i0809 02:35:45.269902 17305datamanager.cc:118] 1: size: 1

i0809 02:35:45.269928 17310datamanager.cc:133] 2: size: 1

i0809 02:35:45.269935 17310datamanager.cc:137] 3: size: 1

i0809 02:35:45.269937 17310datamanager.cc:140] 4: size: 0

b)       出錯時的log順序

出現錯誤時的log順序例如以下。

i0809 02:35:45.271644 17305datamanager.cc:118] 1: size: 1

i0809 02:35:45.271663 17310datamanager.cc:137] 3: size: 1

i0809 02:35:45.271670 17310datamanager.cc:140] 4: size: 0

i0809 02:35:45.271739 17309 datamanager.cc:133]2: size: 0

i0809 02:35:45.271750 17309datamanager.cc:137] 3: size: 0

執行緒號能夠從第三列得出。 17305的執行緒是生產者執行緒,17310和17309為消費者執行緒。從列印的log能夠看除執行的順序例如以下:

a) 初始狀態;

i.   17305:獲得socket_mu_準備向socket_list_中插入socket。

ii.  17309:正處於cond_var_.wait(&socket_mu_);狀態下等待cond_var發生。

iii. 17310 :socket_mu_應該是在試圖

b) 17305執行緒呼叫cond_var_.signal()喚醒17309。此時17309和17310還須要爭奪socket_mu_。應該是17310先得到了socket_mu_所以17309必須再次睡眠。

c) 17310將剛才17305生產的socket消耗了,而且釋放了socket_mu_。

可是此時的socket_list_有變成空的了。 d) 17309得到socket_mu_。呼叫socket_list_.front()

時程式crash。

@@ -129,6 +129,9 @@ voiddatamanager::workentry() 

if (stop_)

break;

單生產者 多消費者模型

問題出處 生產者消費者問題 有乙個生產者在生產產品,這些產品將提供給若干個消費者去消費,為了使生產者和消費者能併發執行,在兩者之間設定乙個有多個緩衝區的緩衝池,生產者將它生產的產品放入乙個緩衝區中,消費者可以從緩衝區中取走產品進行消費,所有生產者和消費者都是非同步方式執行的,但它們必須保持同步,即不...

生產者消費者模型二(單 多模型)

生產者 消費者問題 producer consumer 又名 有界緩衝區 bounded buffer 問題 單生產者 多消費者 設計要點 當緩衝區滿已滿,而此時生產者還想向緩衝區中放入乙個新的資料項時。則讓生產者睡眠,待消費者從緩衝區中取出乙個或多個資料項時再喚醒生產者。同樣的,當緩衝區滿已空,而...

生產者消費者問題之多生產者 單消費者模型

與單生產者和單消費者模型不同的是,多生產者 單消費者模型中可以允許多個生產者同時向產品庫中放入產品。所以除了保護產品庫在多個讀寫執行緒下互斥之外,還需要維護生產者放入產品的計數器,如下 include include include include include static const int ...