Ai
1 Star 0 Fork 0

green-gitee/博客园

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
producer-consumer.cpp 3.93 KB
一键复制 编辑 原始数据 按行查看 历史
green-gitee 提交于 2025-03-28 20:03 +08:00 . Added resources of 18795973.
// producer-consumer.cpp
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
namespace blogs
{
using std::chrono::milliseconds;
using std::condition_variable;
using std::lock_guard;
using std::mutex;
using std::string;
using std::unique_lock;
using std::vector;
class Table
{
private:
vector<string>
__buffer__;
int
const
__capacity__;
int
__head__;
int
__tail__;
int
__count__;
mutex
__mtx__;
condition_variable
__cv__;
public:
Table(int cap)
: __capacity__(cap), __buffer__(cap), __head__(0), __tail__(0), __count__(0)
{
}
void
put(string cake, string name)
{
unique_lock<mutex> lk(__mtx__);
std::printf("%s puts %s\n", name.c_str(), cake.c_str());
__cv__.wait(lk,
[&] {
bool full = __count__ == __capacity__;
if (full)
std::printf("Table is full. %s is waiting...\n", name.c_str());
return !full;
});
__buffer__[__tail__] = cake;
__tail__ = (__tail__ + 1) % __capacity__;
++__count__;
__cv__.notify_all();
}
string
take(string name)
{
unique_lock<mutex> lk(__mtx__);
__cv__.wait(lk,
[&] {
bool idle = __count__ == 0;
if (idle)
std::printf("Table is empty. %s is waiting...\n", name.c_str());
return !idle;
});
string cake(__buffer__[__head__]);
__head__ = (__head__ + 1) % __capacity__;
--__count__;
__cv__.notify_all();
std::printf("%s takes %s\n", name.c_str(), cake.c_str());
return cake;
}
};
class Maker
{
private:
static
mutex
__smtx__;
static
unsigned
__id__;
static
unsigned
__nextid__()
{
lock_guard<mutex> lk(__smtx__);
return ++__id__;
}
string
__name__;
public:
Maker(string nm)
: __name__(nm)
{
}
void
run(Table & table)
{
while (true) {
std::this_thread::sleep_for(milliseconds(std::rand()%1000));
string cake;
cake += "[Cake No.";
cake += std::to_string(__nextid__());
cake += " by ";
cake += __name__;
cake += "]";
table.put(cake, __name__);
}
}
};
unsigned
Maker::__id__ = 0;
mutex
Maker::__smtx__;
class Eater
{
private:
string
__name__;
public:
Eater(string nm)
: __name__(nm)
{
}
void
run(Table & table)
{
while (true) {
string cake = table.take(__name__);
std::this_thread::sleep_for(milliseconds(std::rand()%3000));
}
}
};
void
bye(int sig = SIGTERM)
{
std::printf("\nBye Producer-Consumer...\n\n");
std::exit(sig);
}
} // end of namespace blogs
int
main(int argc, char * argv[])
{
using std::thread;
using blogs::Eater;
using blogs::Maker;
using blogs::Table;
std::signal(SIGINT, blogs::bye);
std::srand(std::time(0));
Table table(3);
Maker m1("Maker-1");
Maker m2("Maker-2");
Maker m3("Maker-3");
Eater e1("Eater-1");
Eater e2("Eater-2");
Eater e3("Eater-3");
thread mt1(&Maker::run, &m1, std::ref(table));
thread mt2(&Maker::run, &m2, std::ref(table));
thread mt3(&Maker::run, &m3, std::ref(table));
thread et1(&Eater::run, &e1, std::ref(table));
thread et2(&Eater::run, &e2, std::ref(table));
thread et3(&Eater::run, &e3, std::ref(table));
mt1.join();
mt2.join();
mt3.join();
et1.join();
et2.join();
et3.join();
blogs::bye();
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/green-gitee/cnblogs.git
git@gitee.com:green-gitee/cnblogs.git
green-gitee
cnblogs
博客园
master

搜索帮助