EventHandler类有一个单例对象来接收来自主线程的事件。它将输入注册到向量,并创建一个运行 lambda 函数的线程,该函数在从向量中删除输入之前等待一段时间,以防止在一段时间内重复执行该输入的事件。
但我在繁忙错误时遇到互斥体被破坏的情况。我不确定它发生在哪里以及如何发生。我什至不确定它是什么意思,因为它不应该作为单例对象被解构。一些帮助将不胜感激。
class EventHandler{
public:
std::mutex simpleLock;
std::vector<UInt32> stuff;
void RegisterBlock(UInt32 input){
stuff.push_back(input);
std::thread removalCallBack([&](UInt32 input){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
simpleLock.lock();
auto it = Find(stuff, input);
if (it != stuff.end())
stuff.erase(it);
simpleLock.simpleLock.unlock();
}, input)
removalCallBack.detach();
}
virtual EventResult ReceiveEvent(UInt32 input){
simpleLock.lock();
if (Find(stuff, input) != stuff.end()){
RegisterBlock(input));
//dostuff
}
simpleLock.simpleLock.unlock();
}
};
正在发生的事情是创建了一个线程
std::thread removalCallBack([&](UInt32 input){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
simpleLock.lock();
...
removalCallBack.detach();
然后自从移除回调是函数的局部变量注册块,当函数退出时,析构函数为移除回调被调用会调用std::终止()
线程析构函数的文档 http://en.cppreference.com/w/cpp/thread/thread/~thread
〜线程(); (自 C++11 起)
销毁线程对象。如果 *this 仍然有一个关联的正在运行的线程(即 joinable() == true),则调用 std::terminate()。
但要看时机,简单锁当线程退出时,它仍然由线程拥有(很忙),根据规范,这会导致未定义的行为,在您的情况下忙碌时被毁 error.
为了避免此错误,您应该允许线程在函数退出后存在(例如,不要将其设为局部变量),或者在函数退出之前阻塞直到线程退出线程::加入
处理线程后的清理可能很棘手,特别是如果它们本质上用作占用相同地址空间的不同程序,并且在这种情况下很多时候manager正如您所想到的那样,线程被创建,其唯一的工作就是回收与线程相关的资源。由于在创建的线程中完成的工作很简单,您的情况会更容易一些移除回调,但仍有清理工作要做。
如果线程对象要通过new创建,那么虽然C++线程对象所代表的系统线程使用的系统资源将被清理,但该对象使用的内存将保持分配状态,直到调用delete为止。
另外,请考虑如果程序在有线程运行时退出,那么线程将被终止,但如果发生这种情况时锁定了互斥体,则将再次出现未定义的行为。
为了保证线程不再运行,通常要做的就是加入它,但是尽管如此this http://en.cppreference.com/w/cpp/thread/thread/join没有说, pthread_join 手册页指出
一旦线程被分离,它就无法使用 pthread_join(3) 连接或再次可连接。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)