我需要在c 中做生產者消費者問題,解決1個消費者和6個生產者,以及1個生產者和6個消費者,以下是問題的陳述。
問題 1:想象一下,您正在一家非常繁忙的餐廳等一些朋友,您正在看著侍應生的作業人員將食物從廚房帶到他們的餐桌上。這是經典的“生產者-消費者”問題的一個例子。服務器有限制,廚房不斷生產食物。考慮到服務器(消費者)有限制和“無限”供應的食物由廚師(制作人)制作。
一種促進識別并因此減少為“生產者-消費者”問題的方法是限制消費者的數量,從而限制膳食的無限數量。在廚房生產。因此,建議存在交通燈來控制服務員將采取的膳食的生產順序。
該程式將類似于:
- 創建一個信號量;
- 創建服務器和廚師執行緒;
- 制作盡可能多的飯菜,并記錄排隊的飯菜數量;
- 服務器執行緒將一直運行,直到它設法提供表中生產的所有餐點;和
- 執行緒必須與主執行緒“連接”。
還要考慮有 6 名廚師和 1 名服務員。如果您愿意,您可以考慮廚師制作一頓飯需要 50 微秒,而服務器需要 10 微秒將飯菜送上餐桌。設定要服務的最大客戶數。在執行結束時,在螢屏上列印哪個廚師最閑,哪個廚師最空閑,以及每位廚師制作了多少餐。
問題 2:考慮上述餐廳。現在考慮有 1 個廚師和 6 個服務員。假設廚師需要 50 微秒來制作一頓飯,而服務器需要 15 微秒將飯菜送到餐桌上。設定要服務的最大客戶數。列印哪個服務器空閑最多和最少,以及每個服務器提供了多少餐點。
我設法解決了 6 個生產者和 1 個消費者,但是對于 6 個消費者和 1 個生產者它不起作用,似乎程式陷入了一些死鎖。如果有人知道如何提供幫助,我將不勝感激。
#include <iostream>
#include <random>
#include <chrono>
#include <thread>
#include <mutex>
#include <deque>
//The mutex class is a synchronization primitive that can be used to protect shared data
//from being simultaneously accessed by multiple threads.
std::mutex semaforo; //semafoto para fazer o controle de acesso do buffer
std::condition_variable notifica; //variavel condicional para fazer a notifica??o de prato consumido/consumido
std::deque<int> buffer; //buffer de inteiros
const unsigned int capacidade_buffer = 10; //tamanho do buffer
const unsigned int numero_pratos = 25; //numeros de pratos a serem produzidos
void produtor()
{
unsigned static int contador_pratos_produzidos = 0;
while (contador_pratos_produzidos < numero_pratos)
{
std::unique_lock<std::mutex> locker(semaforo);
notifica.wait(locker, []
{ return buffer.size() < capacidade_buffer; });
std::this_thread::sleep_for(std::chrono::microseconds(50));
buffer.push_back(contador_pratos_produzidos);
if (contador_pratos_produzidos < numero_pratos)
{
contador_pratos_produzidos ;
}
locker.unlock();
notifica.notify_all();
}
}
void consumidor(int ID, std::vector<int> &consumido)
{
unsigned static int contador_pratos_consumidos = 0;
while (contador_pratos_consumidos < numero_pratos)
{
std::unique_lock<std::mutex> locker(semaforo);
notifica.wait(locker, []
{ return buffer.size() > 0; });
std::this_thread::sleep_for(std::chrono::microseconds(15));
buffer.pop_front();
if (contador_pratos_consumidos < numero_pratos)
{
contador_pratos_consumidos ;
consumido[ID] ;
}
locker.unlock();
notifica.notify_one();
}
}
int main()
{
//vetor para contagem do consumo de cada garcon
std::vector<int> consumido(6, 0);
//vetor de threads garcon(consumidores)
std::vector<std::thread> consumidores;
for (int k = 0; k < 6; k )
{
consumidores.push_back(std::thread(consumidor, k, std::ref(consumido)));
}
//produtor/chef
std::thread p1(produtor);
for (auto &k : consumidores)
{
k.join();
}
p1.join();
int mais_ocioso = 200, menos_ocioso = 0, mais, menos;
for (int k = 0; k < 6; k )
{
std::cout << "Garcon " << k 1 << " entregou " << consumido[k] << " pratos\n";
if (consumido[k] > menos_ocioso)
{
menos = k 1;
menos_ocioso = consumido[k];
}
if (consumido[k] < mais_ocioso)
{
mais = k 1;
mais_ocioso = consumido[k];
}
}
std::cout << "\nO mais ocioso foi o garcon " << mais << " e o menos ocioso foi o garcon " << menos << "\n";
}
uj5u.com熱心網友回復:
消費者和生產者函式中都存在相同的錯誤。我將解釋其中一個,同樣的錯誤也必須在另一個中修復。
unsigned static int contador_pratos_consumidos = 0;
while (contador_pratos_consumidos < numero_pratos)
{
這個static計數器被多個執行執行緒訪問和修改。
多個執行執行緒使用的任何非原子物件都必須正確排序(僅在持有適當的互斥鎖時才能訪問)。
如果您將注意力集中在以上兩行上,很明顯該計數器是在沒有任何互斥鎖保護的情況下訪問的。一旦你意識到這一點,錯誤就很明顯了:在某些時候contador_pratos_consumidos將恰好比 小 1 numero_pratos。當這種情況發生時,您可以讓多個執行執行緒同時評估while條件,并且所有執行緒都會很高興地得出結論,這是真的。
多個執行執行緒然后進入while回圈。一個人將成功獲取互斥鎖并消費“產品”,并完成。剩余的執行執行緒將永遠等待另一個永遠不會到達的“產品”。不會再生產更多的產品。他們沒有湯。
同樣的錯誤也存在于生產者中,只是錯誤的影響相當微妙:最終會生產出比應有的更多的產品。
當然,迂腐地說,所有這些都是未定義的行為,所以任何事情都可能發生,但這些是這種未定義行為的典型的、通常的后果。必須修復兩個錯誤才能使該演算法正常作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359325.html
