我想建立一个帮助类,它可以接受通过std :: bind创建的std :: function),这样我就可以调用这个类从另一个线程:std ::函数结合线程C++ 11失败向量中的调试断言
短的例子:
void loopme() {
std::cout << "yay";
}
main() {
LoopThread loop = { std::bind(&loopme) };
loop.start();
//wait 1 second
loop.stop();
//be happy about output
}
然而,呼吁停止()时,我目前的实施,将提高以下错误:debug assertion Failed , see Image: i.stack.imgur.com/aR9hP.png。
有谁知道为什么错误被抛出? 在这个例子中,我甚至不使用矢量。 当我不从线程内调用loopme,但直接输出到std :: cout时,不会引发错误。
这里全面实施我的课:
class LoopThread {
public:
LoopThread(std::function<void(LoopThread*, uint32_t)> function) : function_{ function }, thread_{ nullptr }, is_running_{ false }, counter_{ 0 } {};
~LoopThread();
void start();
void stop();
bool isRunning() { return is_running_; };
private:
std::function<void(LoopThread*, uint32_t)> function_;
std::thread* thread_;
bool is_running_;
uint32_t counter_;
void executeLoop();
};
LoopThread::~LoopThread() {
if (isRunning()) {
stop();
}
}
void LoopThread::start() {
if (is_running_) {
throw std::runtime_error("Thread is already running");
}
if (thread_ != nullptr) {
throw std::runtime_error("Thread is not stopped yet");
}
is_running_ = true;
thread_ = new std::thread{ &LoopThread::executeLoop, this };
}
void LoopThread::stop() {
if (!is_running_) {
throw std::runtime_error("Thread is already stopped");
}
is_running_ = false;
thread_->detach();
}
void LoopThread::executeLoop() {
while (is_running_) {
function_(this, counter_);
++counter_;
}
if (!is_running_) {
std::cout << "end";
}
//delete thread_;
//thread_ = nullptr;
}
我用于测试下面Googletest代码(但是包含代码的简单方法主要应该工作):
void testfunction(pft::LoopThread*, uint32_t i) {
std::cout << i << ' ';
}
TEST(pfFiles, TestLoop)
{
pft::LoopThread loop{ std::bind(&testfunction, std::placeholders::_1, std::placeholders::_2) };
loop.start();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
loop.stop();
std::this_thread::sleep_for(std::chrono::milliseconds(2500));
std::cout << "Why does this fail";
}
但是在引用代码中没有矢量,你是否忽略了重要的或者你说你不使用向量explcitily? –
我以前没有使用Google Test,但是我认为你的TEST()定义应该包含某种ASSERT()声明? – Mitch
offtopic:'std :: thread'是可移动的,你不需要(并且想要)通过指针存储它并手动删除它 –