熱線電話:0755-23712116
郵箱:contact@shuangyi-tech.com
地址:深圳市寶安區(qū)沙井街道后亭茅洲山工業(yè)園工業(yè)大廈全至科技創(chuàng)新園科創(chuàng)大廈2層2A
0 前言
1 消費者“被動等待”
#include
#include
#include
static std::mutex mtx;
static std::deque<int> dq;
static int productNum = 5;
void Producer()
{
using namespace std::literals::chrono_literals;
for (int i = 1; i <= productNum; ++i) {
mtx.lock();
dq.push_front(i);
std::cout << "Producer 生產(chǎn)產(chǎn)品為: " << i << std::endl;
mtx.unlock();
// std::this_thread::sleep_for(1s);
}
}
void Consumer()
{
while (true) {
if (dq.empty()) {
continue;
}
mtx.lock();
int data = dq.back();
dq.pop_back();
std::cout << "Consumer 消費產(chǎn)品為: " << data << std::endl;
mtx.unlock();
}
}
int main()
{
std::thread t1(Producer);
std::thread t2(Consumer);
t2.join();
t1.join();
std::cin.get();
}
程序運行結(jié)果如下:
如果讓生產(chǎn)者線程每生產(chǎn)一個產(chǎn)品后休息(sleep) 1s,結(jié)果如下:
解釋:該例子中,生產(chǎn)者和消費者分別對應(yīng)兩個線程。隊列中存在物品時,消費者去消費,否則空循環(huán),一直等待。
缺點:當(dāng)雙端隊列中沒有物品時,消費者只會原地死等,不會去催。
2 消費者“主動出擊”
#include
#include
#include
#include
#include
std::mutex mtx;
std::condition_variable cv;
std::vector<int> vec;
int productNum = 5;
void Producer()
{
for (int i = 1; i <= productNum; ++i) {
std::unique_lock<std::mutex> lock(mtx);
while (!vec.empty()) {
cv.wait(lock); // vec 不為空時阻塞當(dāng)前線程
}
vec.push_back(i);
std::cout << "Producer生產(chǎn)產(chǎn)品: " << i << std::endl;
cv.notify_all(); // 釋放線程鎖
}
}
void Consumer()
{
while (true) {
std::unique_lock<std::mutex> lock(mtx);
while (vec.empty()) {
cv.wait(lock); // vec 為空時等待線程鎖。其他線程鎖釋放時,當(dāng)前線程繼續(xù)執(zhí)行
}
int data = vec.back();
vec.pop_back();
std::cout << "Consumer消費產(chǎn)品: " << data << std::endl;
cv.notify_all();
}
}
int main()
{
std::thread t1(Producer);
std::thread t2(Consumer);
t2.join();
t1.join();
std::cin.get();
}
程序運行結(jié)果如下:
解釋:該例子中,生產(chǎn)者和消費者分別對應(yīng)兩個線程。只要 vector 中存在物品時,生產(chǎn)者線程就阻塞,通知消費者線程去消費;vector 中不存在物品時,消費者線程阻塞,通知生產(chǎn)者去生產(chǎn)。
3 線程加入方式 join 和 detach
join:采用 join 方式,t1、t2 亂序執(zhí)行,且外層主線程會等到 t1、t2 都結(jié)束了再繼續(xù)執(zhí)行后面的代碼。
detach:如果采用 detach 方式,t1、t2 亂序執(zhí)行,且脫離了外層主線程。外層主線程執(zhí)行結(jié)束時,t1、t2 可能還沒結(jié)束,但此時程序就退出了。
如涉及侵權(quán),請相關(guān)權(quán)利人與我司聯(lián)系刪除