互斥鎖的版本:
#include <string>
#include <thread>
#include <mutex>
#include <iostream>
using namespace std;
std::mutex data_mutex;
int flag = 0;
void printA(int* a, int size) {
for (int i = 0; i < size; ) {
data_mutex.lock();
if (flag == 0) {
cout << a[i] << endl;
flag = 1;
++i;
}
data_mutex.unlock();
}
}
void printB(char* b, int size) {
for (int i = 0; i < size; ) {
data_mutex.lock();
if (flag == 1) {
cout << b[i] << endl;
flag = 0;
++i;
}
data_mutex.unlock();
}
}
int main()
{
int a[4] = { 1, 2, 3, 4 };
char b[4] = { 'a', 'b', 'c', 'd' };
std::thread tA(&printA, a, 4);
std::thread tB(&printB, b, 4);
tA.join();
tB.join();
return 0;
}
使用互斥鎖+條件變量的版本:
#include <string>
#include <thread>
#include <mutex>
#include <iostream>
using namespace std;
std::mutex data_mutex;
std::condition_variable data_var;
int flag = 0;
void printA(int* a, int size) {
for (int i = 0; i < size; i++) {
std::unique_lock<std::mutex> lck(data_mutex);
data_var.wait(lck, [] {return flag == 0; });
cout << a[i] << endl;
flag = 1;
data_var.notify_all();
}
}
void printB(char* b, int size) {
for (int i = 0; i < size; ++i) {
std::unique_lock<std::mutex> lck(data_mutex);
data_var.wait(lck, [] {return flag == 1; });
cout << b[i] << endl;
flag = 0;
data_var.notify_all();
}
}
int main()
{
int a[4] = { 1, 2, 3, 4 };
char b[4] = { 'a', 'b', 'c', 'd' };
std::thread tA(&printA, a, 4);
std::thread tB(&printB, b, 4);
tA.join();
tB.join();
return 0;
}
PV操作
#include <thread>
#include <mutex>
#include <iostream>
#include <vector>
using namespace std;
const int PRONUM = 10; // 生產者總個數
const int CONSUNUM = 5; // 消費者總個數
const int SUM = 30; // 需要的商品總個數
const int CAP = 20; // 緩衝區長度
vector<int> storage(CAP); // 緩衝區
int cnt = 0; // 倉庫內貨物計數器,判斷是全滿還是全空
mutex mutex_storage;// 保護緩衝區的鎖
condition_variable con_emp;
condition_variable con_full;
static int has_consumed = 0; // 總共消費的
static int has_produced = 0; // 總共生產的
class Pointer {
private:
int p;
public:
Pointer() : p(0){}
int& operator++() {
p++;
if (p == CAP) {
p = 0;
}
return p;
}
int& operator++(int) {
return ++(*this);
}
int& operator*() {
return p;
}
};
Pointer p_em; // 指向第一個空的位置
Pointer p_full; // 指向第一個滿的位置
// 生產者線程
void produce() {
do{
unique_lock<mutex> lck(mutex_storage);
con_emp.wait(lck, []() {return cnt != CAP; });
storage[*p_em] = has_produced;
cnt++;
cout << this_thread::get_id() << "生產了" << storage[*p_em] << "號, 目前有:" << cnt << "個" << endl;
this_thread::sleep_for(std::chrono::milliseconds(100));
p_em++;
has_produced++;
con_full.notify_one();
} while (has_produced <= SUM);
}
void consume() {
do {
unique_lock<mutex> lck(mutex_storage);
con_full.wait(lck, []() {return cnt != 0; });
cnt--;
cout << this_thread::get_id() << "消費了" << storage[*p_full] << "號, 目前有:" << cnt << "個" << endl;
this_thread::sleep_for(std::chrono::milliseconds(500));
p_full++;
has_consumed++;
con_emp.notify_one();
} while (has_consumed <= SUM);
}
int main()
{
vector<thread> vec_p;
vector<thread> vec_c;
for (int i = 0; i < PRONUM; ++i) {
vec_p.push_back(thread(produce));
}
for (int i = 0; i < CONSUNUM; ++i) {
vec_c.push_back(thread(consume));
}
for (int i = 0; i < PRONUM; ++i) {
vec_p[i].join();
}
for (int i = 0; i < CONSUNUM; ++i) {
vec_c[i].join();
}
return 0;
}