c++ - ConnectNamedPipe() 函数在从作为参数传递给新线程的 Functor 的方法中调用时触发“调试错误!abort()”
问题描述
错误
在 Visual Studio 中执行以下操作会触发“ Debug Error! abort() has been called ”:
if(m_handle==INVALID_HANDLE_VALUE) return(false); // no return here, therefore m_handle is valid (?)
if(!m_connected){ // some bool indicating a connection doesn't already exist
if(ConnectNamedPipe(m_handle,NULL)==0){ // --- Abort() message triggered here ----
// ...
}
}
语境
上面的代码是重载函数调用运算符connectClient()
的类方法的一部分;在该重载函数中调用:PipeFunctor
()
connectClient()
void PipeFunctor::operator()() {
connectClient(); // PipeFunctor::connectClient() called here
// ...
}
该connectClient()
方法通过传递给线程的函子间接调用,即:
PipeFunctor pipeF();
// ...
std::thread (std::ref(pipeF));
假设
connectClient()
直接调用时(如下所示),执行相同的违规语句ConnectNamedPipe()
时不会出现 Debug abort()错误:
PipeFunctor pipeF();
// ...
pipeF.connectClient();
这使我相信是线程执行语句std::thread (std::ref(pipeF));
导致了下游问题。
1.有没有一种方法可以通过传递一个包含并随后调用该ConnectNamedPipe()
函数的函子对象来开始一个新线程,而不会产生此调试abort()错误?
2.解决此问题的最佳方法是什么?
所有建议表示赞赏。
谢谢!
附加信息:
在调用有问题的函数之前,从(如下所示)方法m_handle
中(看似成功地)创建了该变量:connectClient()
ConnectNamedPipe()
if(!pipename || *pipename==0) return(false); // no return here. pipeName is a correctly initialized LPTSTR variable
m_handle = CreateNamedPipe(pipename,PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,256*1024,256*1024,5000,NULL);
if(m_handle==INVALID_HANDLE_VALUE){ // produces if(false)
wprintf(L"Creating pipe '%s' failed\n",pipename);
return(false);
}
解决方案
PipeFunctor pipeF();
是一个函数声明(一个名为pipeF
不带参数并返回 a的函数PipeFunctor
)。它不是变量声明,就像您可能想要的那样。PipeFunctor pipeF;
是一个变量声明,就像PipeFunctor pipeF{};
.
在任何情况下,使用 时std::thread
,您都在传递对的引用pipeF
。我的猜测是,pipeF
在线程有机会调用其operator()
. 如果std::thread
回调抛出未捕获的异常(例如通过访问无效PipeFunctor
对象的数据成员) ,则会std::terminate()
被调用,而后者又会std::abort()
默认调用。
推荐阅读
- javascript - WebSocket 不显示 js 警报
- yii - 在 yii 迁移中获取选择查询的数据
- reactjs - 发出太多请求等待 Axios (ReactJS)
- ubuntu - sysctl 设置不会在 wsl2 上持续存在
- swiftui - 如何使用 UI 测试访问 SwiftUI 中不同视图上的按钮?
- sql - How to get data on minute base instead of hourly base?
- asp.net-core - 如何在 Razor 页面上删除 DevExtreme DataGrid 中的行之前显示删除确认对话框?
- html - 如何将样式从 HTML 移动到 CSS?
- macos - 如何像 [phw/peek] 一样使窗口内容透明
- python - 如何模拟单个单元测试的本地时区?