簡體   English   中英

我什么時候必須使用boost :: asio:strand

[英]When do I have to use boost::asio:strand

閱讀boost :: asio的文檔,尚不清楚何時需要使用asio :: strand。 假設我有一個使用io_service的線程,那么可以安全地在套接字上進行如下編寫嗎?

void Connection::write(boost::shared_ptr<string> msg)
{
    _io_service.post(boost::bind(&Connection::_do_write,this,msg));
}

void Connection::_do_write(boost::shared_ptr<string> msg)
{
    if(_write_in_progress)
    {
      _msg_queue.push_back(msg);
    }
    else
    {
      _write_in_progress=true;
      boost::asio::async_write(_socket, boost::asio::buffer(*(msg.get())),
      boost::bind(&Connection::_handle_write,this,
             boost::asio::placeholders::error));
    }
}

void Connection::_handle_write(boost::system::error_code const &error)
{
  if(!error)
  {
    if(!_msg_queue.empty())
    {
          boost::shared_ptr<string> msg=_msg_queue.front();
      _msg_queue.pop_front();
      boost::asio::async_write(_socket, boost::asio::buffer(*(msg.get())),
           boost::bind(&Connection::_handle_write,this,
                   boost::asio::placeholders::error));
        }
    else
    {
      _write_in_progress=false;
    }
  }
}

在多個線程調用Connection :: write(..)的地方,還是我必須使用asio :: strand?

簡短的回答:不,在這種情況下,您不必使用strand

廣義上講, io_service包含功能對象(處理程序)的列表。 在服務上調用post()時,將處理程序放入列表中。 例如,每當異步操作完成時,將處理程序及其參數放入列表中。 io_service::run()執行一個處理程序。 因此,如果像您的情況那樣只有一個線程調用run() ,則不會出現同步問題,也不需要strand
僅當多個線程在同一io_service上調用run()時,才會在N個線程(最多N個並發處理程序)中同時執行多個處理程序。 如果這是一個問題,例如,如果隊列中可能同時有兩個處理程序訪問同一對象,則需要使用strand
您可以將strand視為一組處理程序的一種鎖。 如果線程執行與strand相關的處理程序,則該strand將被鎖定,並在處理程序完成后釋放。 任何其他線程只能執行未與鎖定strand關聯的處理程序。

注意:這個解釋可能是過於簡化和技術上不准確的,但它給在發生什么的一個基本概念io_service和的strand秒。

僅從一個線程調用io_service::run()將使所有事件處理程序在該線程中執行,而不管有多少線程正在調用Connection::write(...) 因此,在沒有可能並發執行處理程序的情況下,這是安全的。 文檔將其稱為隱式鏈

另一方面,如果多個線程正在調用io_service::run() ,那么將需要一個子線程。 這個答案涵蓋了更多的細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM