操作系统:vxWorks 7 23.09
C++17
编译器:Clang
硬件平台:Intel第11代i7 CPU
BSP:英特尔通用 BSP 64 位
我有 2 个线程。其中一个线程称为以太网读取器线程,顾名思义,它从套接字读取数据并将其推送到 std::queue 并通知主线程(处理线程)。
主线程(处理线程)在没有数据要处理时使用
std::condition_variable::wait_for
来让出 CPU。之前我使用忙等待设计模式进行处理。
我希望减少使用
std::condition_variable::wait_for
时唤醒线程/任务的延迟。早些时候,当我不使用
std::condition_variable::wait_for
时,即在无限循环内使用忙等待设计模式时,我处理以太网数据的整个处理时间为 3-15 微秒。
当我使用
std::condition_variable::wait_for
时,处理线程需要 50-250 微秒才能唤醒。其余处理在 15 微秒内完成。如果我将处理线程让出 CPU,以防没有数据要处理,我正在寻找减少唤醒延迟的策略。
我并不专注于
std::condition_variable::wait_for
,如果有其他方法提供更好的延迟/响应时间,我准备改变我的方法。输出:
Calling Notify All : 1731492554671893
Inside Wait For : 1731492554672106
Calling Notify All : 1731492557672289
Inside Wait For : 1731492557672506
Calling Notify All : 1731492560672740
Inside Wait For : 1731492560672901
代码:
wait_for_event.hpp
#include <mutex>
#include <chrono>
#include <iostream>
#include <optional>
#include <condition_variable>
namespace wfe
{
enum class WaitForEventStatus : std::uint8_t
{
Error = 0,
Timeout,
NoTimeout,
NoError //Required for just wait
};
class WaitForEvent
{
private:
std::mutex mutex;
std::condition_variable condition_variable;
public:
void notify_one(void) noexcept
{
this->condition_variable.notify_one();
}
void notify_all(void) noexcept
{
this->condition_variable.notify_all();
}
void wait(void)
{
std::unique_lock<std::mutex> lock(this->mutex);
this->condition_variable.wait(lock);
}
template <class Rep, class Period>
WaitForEventStatus wait_for(const std::chrono::duration<Rep,Period>& wait_time)
{
try
{
std::unique_lock<std::mutex> lock(this->mutex);
auto return_status = this->condition_variable.wait_for(lock, wait_time);
if(return_status == std::cv_status::no_timeout)
{
return WaitForEventStatus::NoTimeout;
}
else
{
return WaitForEventStatus::Timeout;
}
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
return WaitForEventStatus::Error;
}
}
template <class Clock, class Duration>
WaitForEventStatus wait_until(const std::chrono::time_point<Clock,Duration>& abs_time)
{
try
{
std::unique_lock<std::mutex> lock(this->mutex);
auto return_status = this->condition_variable.wait_until(lock, abs_time);
if(return_status == std::cv_status::no_timeout)
{
return WaitForEventStatus::NoTimeout;
}
else
{
return WaitForEventStatus::Timeout;
}
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
return WaitForEventStatus::Error;
}
}
WaitForEvent() = default;
~WaitForEvent() = default;
};
}
主.cpp
#include <mutex>
#include <thread>
#include <chrono>
#include <iostream>
#include <condition_variable>
#include "wait_for_event.hpp"
wfe::WaitForEvent event;
void thread_runner(void)
{
while (true)
{
// Code to read data from socket and push the data in queue
std::this_thread::sleep_for (std::chrono::seconds(3));//Only for testing - not on live code
std::cout << "Calling Notify All : " << std::chrono::duration_cast<std::chrono::microseconds>
(std::chrono::system_clock::now().time_since_epoch()).count() << std::endl;
event.notify_all();
}
}
int main(int argc, char const *argv[])
{
std::thread t {thread_runner};
while (true)
{
auto return_status = event.wait_for(std::chrono::seconds(1));
if(return_status == wfe::WaitForEventStatus::Timeout)
{
//std::cout << "WaitForEventStatus::Timeout\n";
}
else if(return_status == wfe::WaitForEventStatus::NoTimeout)
{
//std::cout << "WaitForEventStatus::NoTimeout\n";
std::cout << "Inside Wait For : " << std::chrono::duration_cast<std::chrono::microseconds>
(std::chrono::system_clock::now().time_since_epoch()).count() << std::endl;
}
}
return 0;
}
我认为实现极低延迟的唯一方法是使用软件中断。
另一种选择是使用更轻量的同步原语,例如二进制信号量。
事件标志(eventLib)也很高效。