在使用C++ MJPEG流服务器时,ASIO随机报头丢失
我想我正面临一个boost::asio线程安全问题。让我解释一下: 背景: 我在Ubuntu 14.04上使用Boost1.68和G++4.8.4在使用C++ MJPEG流服务器时,ASIO随机报头丢失,c++,boost,thread-safety,boost-asio,mjpeg,C++,Boost,Thread Safety,Boost Asio,Mjpeg,我想我正面临一个boost::asio线程安全问题。让我解释一下: 背景: 我在Ubuntu 14.04上使用Boost1.68和G++4.8.4 我编写C++代码来制作MJPEG服务器。< /P> 以下是我的一些代码示例,其工作原理非常简单: 代码解释 1填写HTTP头 2以HandleMJPEG作为回调调用doWrite 3 doWrite使用HandleMJPEG作为回调调用async_write 4手册JPEG: 4.1将-JPEG边界添加到流中 4.2回调doWrite,再次调用Han
我编写C++代码来制作MJPEG服务器。< /P> 以下是我的一些代码示例,其工作原理非常简单:
代码解释 1填写HTTP头 2以HandleMJPEG作为回调调用doWrite 3 doWrite使用HandleMJPEG作为回调调用async_write 4手册JPEG: 4.1将-JPEG边界添加到流中 4.2回调doWrite,再次调用HandleMJPEG 4.3 实际代码 TL;博士 问题在于:这段代码90%的时间都在工作。有时,当我想在Firefox 66.0.3 Linux浏览器上查看流时,会出现一个下载弹出窗口,而不是显示图像 当我调查这些包时,似乎有一些标题缺失或拼写错误: 1/一切正常时 2/当它不好的时候这就是为什么怀疑boost asio中存在线程安全问题的原因,但我不知道从何处查看…您有悬而未决的参考。您的问题是std::bind 简介:当您有一个具有成员功能栏的类Foo时: 然后调用std::bind&Foo::bar,f,std::bind返回一个functor,它将f存储为副本 现在让我们回到您的代码:
doWrite(
std::bind(&net::Reply::toBuffers, _reply), // <---- [1]
std::bind(&Connection::handleMJPEG, this),
"'MJPEG Stream init header'");
在[2]中,toBuffer是从std::bind返回的函子的包装器。toBuffer是局部变量。在第[3]行中,您调用toBuffer,它返回常量缓冲区以获得一个_reply的副本-它不引用原始的_reply!异步写入立即返回[4]。doWrite结束,toBuffer被销毁,而由async_write启动的Boost lib机制中的某个地方的任务工作,它正在访问toBuffer返回的常量缓冲区——这里有悬空引用
调用bind时,您可以通过指针传递_reply-这样您将引用同一个_reply实例:
std::bind(&net::Reply::toBuffers, &_reply),
哇,谢谢你的充分解释^^事后看起来很明显,但我在这一点上被卡住了一段时间!非常感谢:-
doWrite(
std::bind(&net::Reply::toBuffers, _reply), // <---- [1]
std::bind(&Connection::handleMJPEG, this),
"'MJPEG Stream init header'");
void Connection::doWrite(
std::function<std::vector<boost::asio::const_buffer>()> toBuffer, // [2]
std::function<void()> callbackOnSuccess,
const std::string& logInfo)
{
auto self(shared_from_this());
boost::asio::async_write(
_socket,
toBuffer(), // [3]
boost::asio::bind_executor( ....
...
));
// [4]
}
std::bind(&net::Reply::toBuffers, &_reply),