std :: bindで作成されたstd ::関数を受け入れるヘルパークラスを作成したいので、このクラスを再描画することができますstd :: functionとスレッドC++ 11との組み合わせでベクトル内のデバッグアサーションが失敗する
短い例:別のスレッドからdebug assertion Failed , see Image: i.stack.imgur.com/aR9hP.png:停止を呼び出すとき
void loopme() {
std::cout << "yay";
}
main() {
LoopThread loop = { std::bind(&loopme) };
loop.start();
//wait 1 second
loop.stop();
//be happy about output
}
ただし、()私の現在の実装では、次のエラーが発生します。
エラーがスローされる理由は誰にも分かりますか? この例ではベクトルを使用していません。 スレッド内から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;
}
私は(ただし、コードを含む単純なmainメソッドが動作するはずです)テストのために、次の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";
}
ただし、引用符で囲まれたコードはありません。重要な部分は省略しましたか、またはあなたはベクターを明示的に使用しないと言っていますか? –
以前はGoogle Testを使っていませんでしたが、あなたのTEST()定義には何らかのASSERT()宣言が含まれているはずですか? – Mitch
offtopic: 'std :: thread'は動かすことができます。ポインタでそれを保存して手動で削除する必要はありません。 –