MyQueue クラスを定義しました。このクラスには、キュー q と、キューから要素をポップするために使用されるクラス関数 PopFromQueue が含まれています。同時に、キューに要素を追加するための静的関数 PushToQueue も定義します。PushToQueue 関数では、スレッドの安全性を確保するために静的ミューテックス mtx と条件変数 cv を使用します。
main 関数では、MyQueue オブジェクト q を作成し、2 つのスレッド t1 (プロデューサー) と t2 (コンシューマー) をそれぞれ開始しました。プロデューサでは、MyQueue::pushToQueue 静的関数を使用して要素をキューに追加し、コンシューマでは、popFromQueue クラス関数を使用してキューから要素をポップします。プロデューサーとコンシューマーの間では、プログラムをより現実的にするために this_thread::sleep_for 関数を使用して作業時間をシミュレートしていることに注意してください。
ソースコードは次のとおりです
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
class MyQueue {
public:
void popFromQueue() {
unique_lock<mutex> lock(mtx);
cv.wait(lock, [this]() {
return !q.empty(); }); // 等待队列非空
int value = q.front();
q.pop();
cout << "Pop from queue: " << value << endl;
}
static void pushToQueue(queue<int>& q, int value) {
unique_lock<mutex> lock(mtx);
q.push(value);
cout << "Push to queue: " << value << endl;
cv.notify_one(); // 通知等待的线程
}
private:
static mutex mtx;
static condition_variable cv;
queue<int> q;
};
mutex MyQueue::mtx;
condition_variable MyQueue::cv;
void producer(MyQueue& q) {
for (int i = 1; i <= 5; ++i) {
MyQueue::pushToQueue(q.q, i);
this_thread::sleep_for(chrono::milliseconds(500)); // 等待0.5秒
}
}
void consumer(MyQueue& q) {
for (int i = 1; i <= 5; ++i) {
q.popFromQueue();
this_thread::sleep_for(chrono::milliseconds(1000)); // 等待1秒
}
}
int main() {
MyQueue q;
thread t1(producer, ref(q));
thread t2(consumer, ref(q));
t1.join();
t2.join();
return 0;
}
上記のコードを実行すると、プロデューサーがキューに要素を追加し、コンシューマーがキューから要素をポップし、正しい情報を出力し、プログラムが正しく待機して終了することがわかります。