Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 使用boost';s SSL asio代码,异步写入一些挂起_Multithreading_Ssl_Boost Asio - Fatal编程技术网

Multithreading 使用boost';s SSL asio代码,异步写入一些挂起

Multithreading 使用boost';s SSL asio代码,异步写入一些挂起,multithreading,ssl,boost-asio,Multithreading,Ssl,Boost Asio,我有一些使用Boost的SSL ASIO库的多线程代码。代码是多线程的,但是每个SSL连接都有一个互斥体,对async.*函数的调用都是通过保持互斥体来完成的 我有时会看到我的代码陷入停顿。有一根线卡住了。线程卡在bio_write中。 堆栈跟踪如下所示: #0 0x00000000010a974f in bio_write () #1 0x00000000010a3529 in BIO_write () #2 0x000000000105fe72 in ssl3_write_p

我有一些使用Boost的SSL ASIO库的多线程代码。代码是多线程的,但是每个SSL连接都有一个互斥体,对
async.*
函数的调用都是通过保持互斥体来完成的

我有时会看到我的代码陷入停顿。有一根线卡住了。线程卡在
bio_write
中。 堆栈跟踪如下所示:

#0  0x00000000010a974f in bio_write ()   

#1  0x00000000010a3529 in BIO_write ()

#2  0x000000000105fe72 in ssl3_write_pending ()

#3  0x0000000001060b02 in ssl3_write_bytes ()

#4  0x0000000000cce43a in boost::asio::ssl::detail::engine::do_write
(this=0x1e618a0, data=0x234c7b0, length=189) at
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:294

#5  0x0000000000cce109 in boost::asio::ssl::detail::engine::perform(this=0x1e618a0, op=(int
(boost::asio::ssl::detail::engine::*)(boost::asio::ssl::detail::engine *
const, void *, std::size_t)) 0xcce3fc<boost::asio::ssl::detail::engine::do_write(void*, unsigned long)>,
data=0x234c7b0, length=189, ec=..., bytes_transferred=0x7fff8ad74d48) at
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:219

#6  0x0000000000ccdd23 in boost::asio::ssl::detail::engine::write
(this=0x1e618a0, data=..., ec=..., bytes_transferred=@0x7fff8ad74d48: 0) at
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:137

#7  0x0000000000dac504 in boost::asio::ssl::detail::write_op<boost::asio::mutable_buffers_1>::operator()
(this=0x7fff8ad74d20, eng=..., ec=..., bytes_transferred=@0x7fff8ad74d48: 0)
at /usr/include/boost/asio/ssl/detail/write_op.hpp:51

#8  0x0000000000da9d8a in boost::asio::ssl::detail::io_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> >,
boost::asio::ssl::detail::write_op<boost::asio::mutable_buffers_1>,
boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> > >,
boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t,
boost::_bi::bind_t<void, boost::_mfi::mf2<void, Peer,
boost::system::error_code const&, unsigned long>,
boost::_bi::list3<boost::_bi::value<boost::shared_ptr<Peer> >, boost::arg<1>
(*)(), boost::arg<2> (*)()> > > >::operator() (this=0x7fff8ad74d10, ec=..., 
bytes_transferred=0, start=1) at /usr/include/boost/asio/ssl/detail/io.hpp:136

#9  0x0000000000da7f42 in boost::asio::ssl::detail::async_io<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> >,
boost::asio::ssl::detail::write_op<boost::asio::mutable_buffers_1>,
boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> > >,
boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t,
boost::_bi::bind_t<void, boost::_mfi::mf2<void, Peer,
boost::system::error_code const&, unsigned long>,
boost::_bi::list3<boost::_bi::value<boost::shared_ptr<Peer> >, boost::arg<1> (*)(),
boost::arg<2> (*)()> > > > (next_layer=..., core=..., op=...,
handler=...) at /usr/include/boost/asio/ssl/detail/io.hpp:322

#10 0x0000000000da634d in
boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> >
>::async_write_some<boost::asio::mutable_buffers_1,
boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> > >,
boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t,
boost::_bi::bind_t<void, boost::_mfi::mf2<void, Peer,
boost::system::error_code const&, unsigned long>,
boost::_bi::list3<boost::_bi::value<boost::shared_ptr<Peer> >, boost::arg<1>
(*)(), boost::arg<2> (*)()> > > > (this=0x1e61880, buffers=..., handler=...)
at /usr/include/boost/asio/ssl/stream.hpp:502

#11 0x0000000000da3032 in
boost::asio::detail::write_op<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> > >,
boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t,
boost::_bi::bind_t<void, boost::_mfi::mf2<void, Peer,
boost::system::error_code const&, unsigned long>,
boost::_bi::list3<boost::_bi::value<boost::shared_ptr<Peer> >, boost::arg<1>
(*)(), boost::arg<2> (*)()> > >::operator() (this=0x7fff8ad74f00, ec=...,   
bytes_transferred=0, start=1) at /usr/include/boost/asio/impl/write.hpp:250 

#12 0x0000000000d9ffbb in
boost::asio::async_write<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp> > >,
boost::asio::mutable_buffers_1, boost::_bi::bind_t<void,
boost::_mfi::mf2<void, Peer, boost::system::error_code const&, unsigned
long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<Peer> >,  
boost::arg<1> (*)(), boost::arg<2> (*)()> > > (s=..., buffers=...,     
handler=...) at /usr/include/boost/asio/impl/write.hpp:585
bio写入中的0 0x00000000010a974f(
)
#1 0x00000000010a3529在BIO_写入中()
#ssl3中的2 0x000000000105fe72写入挂起()
#3 0x0000000001060b02,单位为ssl3写入字节()
#boost::asio::ssl::detail::engine::do_write中的4 0x0000000000cce43a
(此参数=0x1e618a0,数据=0x234c7b0,长度=189)在
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:294
#boost::asio::ssl::detail::engine::perform中的5 0x0000000000cce109(this=0x1e618a0,op=(int
(boost::asio::ssl::detail::engine::*)(boost::asio::ssl::detail::engine*
常数,void*,std::size_t))0xcce3fc,
数据=0x234c7b0,长度=189,ec=…,字节(传输=0x7fff8ad74d48)
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:219
#boost::asio::ssl::detail::engine::write中的6 0x0000000000ccdd23
(this=0x1e618a0,data=…,ec=…,bytes_transfer=@0x7fff8ad74d48:0)位于
/usr/include/boost/asio/ssl/detail/impl/engine.ipp:137
#boost::asio::ssl::detail::write_op::operator()中的7 0x0000000000dac504
(this=0x7fff8ad74d20,eng=…,ec=…,传输的字节数=@0x7fff8ad74d48:0)
at/usr/include/boost/asio/ssl/detail/write_op.hpp:51
#boost::asio::ssl::detail::io_op::operator()中的8 0x0000000000da9d8a(this=0x7fff8ad74d10,ec=。。。,
在/usr/include/boost/asio/ssl/detail/io处传输的字节数=0,起始值=1)。hpp:136
#boost::asio::ssl::detail::async_io中的9 0x0000000000da7f42(下一个_层=…,核心=…,操作=。。。,
handler=…)位于/usr/include/boost/asio/ssl/detail/io.hpp:322
#10 0x0000000000da634d英寸
boost::asio::ssl::stream::async_write_some(this=0x1e61880,buffers=…,handler=…)
at/usr/include/boost/asio/ssl/stream.hpp:502
#11 0x0000000000da3032英寸
boost::asio::detail::write_op::operator()。。。,
在/usr/include/boost/asio/impl/write处传输的字节数=0,起始值=1)。hpp:250
#12 0x0000000000d9ffbb英寸
boost::asio::异步写入(s=…,缓冲区=。。。,
handler=…)位于/usr/include/boost/asio/impl/write.hpp:585

有什么想法吗?

如果您能提供代码,可能会有所帮助。仅仅从堆栈跟踪就很难分析它。如果出于某种原因您无法提供代码,那么以下是一些想法:

bio_write是一种开放式SSL方法,用于将数据写入套接字。如果你想直接打电话,可能会有一些问题。几个月前,我曾要求帮助尝试使用它,但没有得到任何答案

我还将ASIO与SSL一起使用。我的代码使用一个线程将消息写入套接字,另一个线程处理从套接字读取消息。我的客户机正在与多个服务器通信,但总共有两个线程来处理所有服务器上的所有套接字I/O。以下是我向套接字写入的代码,到目前为止,它在Windows下没有问题:

void SSLSocket::SendWorkerThread(SSLSocket* psSLS)
{
   // This thread method that gets called to process the messages to be sent to the server.
   //
   // Since this has to be a static method, call a method on the class to handle server requests.
   psSLS->ProcessSendRequests();
}

void SSLSocket::ProcessSendRequests()
{
   // This method handles sending msgs to the server.
   //
   std::stringstream ss;
   DWORD WaitResult;
   Log.LogString("SSLSocket::ProcessSendRequests: Worker thread " + Logger::NumberToString(boost::this_thread::get_id()) + " started.\n", LogInfo);
   // Loop until the user quits, or an error of some sort is thrown.
   try
   {
      do
      {
         // If there are one or more msgs that need to be sent to a server, then send them out.
         if (SendMsgQ.Count() > 0)
         {
            Message* pMsg = SendMsgQ.Front();
            SSLSocket* pSSL = pMsg->pSSL;
            SendMsgQ.Pop();
            const Byte* pBuf = pMsg->pBuf;
            const int BytesInMsg = pMsg->BytesInMsg;
            boost::system::error_code Error;
            {
               Locking CodeLock(SocketLock); // Single thread the code.
               // unsigned int BytesTransferred = boost::asio::write(*pSSL->pSocket, boost::asio::buffer(pBuf, BytesInMsg), Error);
               boost::asio::async_write(*pSSL->pSocket, boost::asio::buffer(pBuf, BytesInMsg), boost::bind(&SSLSocket::HandleWrite, this,
                  boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
            }
            ss << "SSLSocket::ProcessSendRequests: # bytes sent = " << BytesInMsg << "\n";
            Log.LogString(ss.str(), LogDebug2);
            Log.LogBuf(pBuf, BytesInMsg, DisplayInHex, LogDebug3);
         }
         else
         {
            // Nothing to send, so go into a wait state.
            WaitResult = WaitForSingleObject(hEvent, INFINITE);
            if (WaitResult != 0L)
            {
               Log.LogString("SSLSocket::ProcessSendRequests: WaitForSingleObject event error.  Code = " + Logger::NumberToString(GetLastError()) + ". \n", LogError);
            }
         }
      } while (ReqAlive);
      Log.LogString("SSLSocket::ProcessSendRequests: Worker thread " + Logger::NumberToString(boost::this_thread::get_id()) + " done.\n", LogInfo);
   }
   catch (std::exception& e)
   {
      stringstream ss;
      ss << "SSLSocket::ProcessSendRequests: threw an error - " << e.what() << ".\n";
      Log.LogString(ss.str(), LogError);
      Stop();
   }
}
void SSLSocket::SendWorkerThread(SSLSocket*psSLS)
{
//此线程方法被调用以处理要发送到服务器的消息。
//
//因为这必须是一个静态方法,所以在类上调用一个方法来处理服务器请求。
psSLS->ProcessSendRequests();
}
void SSLSocket::ProcessSendRequests()
{
//此方法处理向服务器发送MSG。
//
std::stringstream-ss;
德沃德·韦特Result;
Log.LogString(“SSLSocket::ProcessSendRequests:Worker线程”+Logger::NumberString(boost::this_线程::get_id())+“started.\n”,LogInfo);
//循环,直到用户退出,或者抛出某种错误。
尝试
{
做
{
//如果有一个或多个MSG需要发送到服务器,则将其发送出去。
如果(SendMsgQ.Count()>0)
{
Message*pMsg=SendMsgQ.Front();
SSLSocket*pSSL=pMsg->pSSL;
SendMsgQ.Pop();
常量字节*pBuf=pMsg->pBuf;
常量int BytesInMsg=pMsg->BytesInMsg;
boost::system::error\u code error;
{
锁定代码锁(SocketLock);//单线程执行代码。
//unsigned int bytesttransferred=boost::asio::write(*pSSL->pSocket,boost::asio::buffer(pBuf,BytesInMsg),Error);
boost::asio::async_write(*pSSL->pSocket,boost::asio::buffer(pBuf,BytesInMsg),boost::bind(&SSLSocket::HandleWrite,this,
boost::asio::placeholders::error,boost::asio::placeholders::bytes_transfer));
}

ss这是多线程问题的结果

对于大多数Boost.Asio对象,在一个对象上挂起多个异步操作是安全的;只是指定对该对象的并发调用是不安全的。然而,它通常不会在某些类型上出现问题,例如。但是,强调:

应用程序还必须确保所有异步操作都在同一隐式或显式串中执行


在您的情况下,解决方案是由同一个链调用每个组合操作的完成处理程序。这将导致在链中调用所有操作。有关线程安全性和链的细微差别细节的更多详细信息,请考虑阅读答案。

boost版本可能与此相关,您可以将其添加到您的问题中吗?我说这是beca使用在boost 1.47中重写的SSL实现。假设这是流的唯一操作是否安全?否则可能会导致未定义的行为。例如,仅锁定互斥锁是不够的;异步写入(…);unlock mutex;
因为在调用完成处理程序之前操作仍在运行。Boost 1.50。我仔细检查了我们的一个未完成写入逻辑是否正确。我们在发布写入时设置了一个标志