#include "iostream"
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unistd.h>
using namespace std;
static const int itemRepositorySize = 10;
static const int itemToProduce = 50;
struct ItemReposity{
int itemBuffer[itemRepositorySize];
size_t readPosition;
size_t writePosition;
mutex mtx;
condition_variable repoNotFull;
condition_variable repoNotEmpty;
}gItemReposity;
void produceItem(ItemReposity* ir, int item)
{
std::unique_lock<std::mutex> lck(ir->mtx);
while(((ir->writePosition + 1) % itemRepositorySize) == ir->readPosition)
{
cout << "生产的地方满了..." <<endl;
(ir->repoNotFull).wait(lck);
}
(ir->itemBuffer)[ir->writePosition] = item;
(ir->writePosition)++;
if(ir->writePosition == itemRepositorySize)
{
ir->writePosition = 0;
}
(ir->repoNotEmpty).notify_all();
lck.unlock();
}
int consumeItem(ItemReposity* ir)
{
int data;
std::unique_lock<std::mutex> lck(ir->mtx);
while(ir->writePosition == ir->readPosition)
{
cout << "已经消费完了,请生产..." <<endl;
(ir->repoNotEmpty).wait(lck);
}
data = (ir->itemBuffer)[ir->readPosition];
(ir->readPosition)++;
if(ir->readPosition == itemRepositorySize)
{
ir->readPosition = 0;
}
(ir->repoNotFull).notify_all();
lck.unlock();
return data;
}
void ProducerTask()
{
for (int i = 1; i <= itemToProduce; ++i) {
sleep(1);
std::cout << "正在生产第 " << i << "个 产品..." << std::endl;
produceItem(&gItemReposity, i);
}
}
void ConsumerTask()
{
static int cnt = 0;
while(1) {
int item = consumeItem(&gItemReposity);
std::cout << "正在消费第 " << item << "个产品" << std::endl;
if (++cnt == itemToProduce) break;
}
}
void InitItemRepository(ItemReposity *ir)
{
ir->writePosition = 0;
ir->readPosition = 0;
}
int main()
{
InitItemRepository(&gItemReposity);
std::thread producer(ProducerTask);
std::thread consumer(ConsumerTask);
producer.join();
consumer.join();
return 0;
}
#include <unistd.h>
#include <cstdlib>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
static const int kItemRepositorySize = 4;
static const int kItemsToProduce = 10;
struct ItemRepository {
int item_buffer[kItemRepositorySize];
size_t read_position;
size_t write_position;
size_t item_counter;
std::mutex mtx;
std::mutex item_counter_mtx;
std::condition_variable repo_not_full;
std::condition_variable repo_not_empty;
} gItemRepository;
typedef struct ItemRepository ItemRepository;
void ProduceItem(ItemRepository *ir, int item)
{
std::unique_lock<std::mutex> lock(ir->mtx);
while(((ir->write_position + 1) % kItemRepositorySize)
== ir->read_position) {
std::cout << "Producer is waiting for an empty slot...\n";
(ir->repo_not_full).wait(lock);
}
(ir->item_buffer)[ir->write_position] = item;
(ir->write_position)++;
if (ir->write_position == kItemRepositorySize)
ir->write_position = 0;
(ir->repo_not_empty).notify_all();
lock.unlock();
}
int ConsumeItem(ItemRepository *ir)
{
int data;
std::unique_lock<std::mutex> lock(ir->mtx);
while(ir->write_position == ir->read_position) {
std::cout << "Consumer is waiting for items...\n";
(ir->repo_not_empty).wait(lock);
}
data = (ir->item_buffer)[ir->read_position];
(ir->read_position)++;
if (ir->read_position >= kItemRepositorySize)
ir->read_position = 0;
(ir->repo_not_full).notify_all();
lock.unlock();
return data;
}
void ProducerTask()
{
bool ready_to_exit = false;
while(1) {
sleep(1);
std::unique_lock<std::mutex> lock(gItemRepository.item_counter_mtx);
if (gItemRepository.item_counter < kItemsToProduce) {
++(gItemRepository.item_counter);
ProduceItem(&gItemRepository, gItemRepository.item_counter);
std::cout << "Producer thread " << std::this_thread::get_id()
<< " is producing the " << gItemRepository.item_counter
<< "^th item" << std::endl;
} else ready_to_exit = true;
lock.unlock();
if (ready_to_exit == true) break;
}
std::cout << "Producer thread " << std::this_thread::get_id()
<< " is exiting..." << std::endl;
}
void ConsumerTask()
{
static int item_consumed = 0;
while(1) {
sleep(1);
++item_consumed;
if (item_consumed <= kItemsToProduce) {
int item = ConsumeItem(&gItemRepository);
std::cout << "Consumer thread " << std::this_thread::get_id()
<< " is consuming the " << item << "^th item" << std::endl;
} else break;
}
std::cout << "Consumer thread " << std::this_thread::get_id()
<< " is exiting..." << std::endl;
}
void InitItemRepository(ItemRepository *ir)
{
ir->write_position = 0;
ir->read_position = 0;
ir->item_counter = 0;
}
int main()
{
InitItemRepository(&gItemRepository);
std::thread producer1(ProducerTask);
std::thread producer2(ProducerTask);
std::thread producer3(ProducerTask);
std::thread producer4(ProducerTask);
std::thread consumer(ConsumerTask);
producer1.join();
producer2.join();
producer3.join();
producer4.join();
consumer.join();
}