c++ 类似与c# 线程 AutoResetEvent 和 ManualResetEvent的实现
在 C++ 中,没有直接类似于 C# 的 AutoResetEvent
和 ManualResetEvent
的类,但可以通过一些线程同步机制来实现类似的功能。C++ 提供了一些线程同步原语,如 std::condition_variable
和 std::mutex
,这些可以用来模拟类似于 C# 中 AutoResetEvent
和 ManualResetEvent
的行为。
AutoResetEvent
和 ManualResetEvent
的基本区别
AutoResetEvent
:每次信号被设置后,它只能唤醒一个等待线程,且会自动重置为未信号状态。ManualResetEvent
:每次信号被设置后,它会保持信号状态,直到被显式重置,所有等待线程都会被唤醒。
C++ 中的替代方案
1. 使用 std::condition_variable
来实现 AutoResetEvent
在 C++ 中,std::condition_variable
可以用来模拟类似于 AutoResetEvent
的行为。std::condition_variable
会让线程在某个条件上等待,当条件满足时,通知一个或所有等待的线程继续执行。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
class AutoResetEvent {
public:
AutoResetEvent(bool initial_state = false)
: signaled(initial_state) {}
// 唤醒一个线程
void Set() {
std::lock_guard<std::mutex> lock(mutex_);
signaled = true;
cv_.notify_one(); // 唤醒一个等待线程
}
// 等待线程被唤醒
void Wait() {
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this]() { return signaled; }); // 等待直到 signaled 为 true
signaled = false; // 唤醒后自动重置为未信号状态
}
private:
bool signaled; // 是否处于信号状态
std::mutex mutex_;
std::condition_variable cv_;
};
void ThreadA(AutoResetEvent& are)
{
std::cout << "线程A开始等待...\n";
are.Wait();
std::cout << "线程A被唤醒,继续执行\n";
}
void ThreadB(AutoResetEvent& are)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "线程B设置信号\n";
are.Set();
}
int main() {
AutoResetEvent are;
std::thread t1(ThreadA, std::ref(are)); // 线程A等待
std::thread t2(ThreadB, std::ref(are)); // 线程B设置信号
t1.join();
t2.join();
return 0;
}
代码说明:
AutoResetEvent
类:封装了std::condition_variable
和std::mutex
,并通过一个布尔变量signaled
来标记是否处于信号状态。调用Set()
方法时会唤醒一个等待线程,调用Wait()
方法时会让当前线程等待信号。Wait()
:当signaled
为true
时,线程会被唤醒,并且signaled
会自动重置为false
,就像AutoResetEvent
的行为。
2. 使用 std::condition_variable
和 std::atomic<bool>
来实现 ManualResetEvent
与 AutoResetEvent
类似,ManualResetEvent
会在 Set()
后保持信号状态,直到调用 Reset()
。可以通过使用 std::atomic<bool>
来维护信号状态,这样可以使多个线程在 Set()
后被唤醒。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>
class ManualResetEvent {
public:
ManualResetEvent(bool initial_state = false)
: signaled(initial_state) {}
// 唤醒所有等待线程
void Set() {
std::lock_guard<std::mutex> lock(mutex_);
signaled = true;
cv_.notify_all(); // 唤醒所有等待线程
}
// 重置为未信号状态
void Reset() {
std::lock_guard<std::mutex> lock(mutex_);
signaled = false;
}
// 等待线程被唤醒
void Wait() {
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this]() { return signaled; }); // 等待直到 signaled 为 true
}
private:
std::atomic<bool> signaled; // 信号状态
std::mutex mutex_;
std::condition_variable cv_;
};
void ThreadA(ManualResetEvent& mre)
{
std::cout << "线程A开始等待...\n";
mre.Wait();
std::cout << "线程A被唤醒,继续执行\n";
}
void ThreadB(ManualResetEvent& mre)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "线程B设置信号\n";
mre.Set(); // 设置信号
}
int main() {
ManualResetEvent mre;
std::thread t1(ThreadA, std::ref(mre)); // 线程A等待
std::thread t2(ThreadB, std::ref(mre)); // 线程B设置信号
t1.join();
t2.join();
return 0;
}
代码说明:
ManualResetEvent
类:使用std::atomic<bool>
来保持信号状态,Set()
会将状态设置为true
并唤醒所有等待的线程,Reset()
会将状态重置为false
。Set()
:设置信号状态并唤醒所有等待的线程。Wait()
:等待直到信号状态为true
。Reset()
:手动重置信号状态,使得线程再次进入等待状态。
总结
AutoResetEvent
可以通过std::condition_variable
和一个布尔标志来模拟,调用Wait()
会让线程等待信号,Set()
会唤醒一个线程并自动重置信号状态。ManualResetEvent
可以通过std::condition_variable
和std::atomic<bool>
来模拟,Set()
会保持信号状态,直到显式调用Reset()
重置状态。
这些 C++ 代码示例演示了如何利用 std::condition_variable
和 std::mutex
来实现类似于 C# 中的 AutoResetEvent
和 ManualResetEvent
的功能。
原文地址:https://blog.csdn.net/qq_22642239/article/details/144745752
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!