2013-05-06 39 views
7

Đọc tài liệu về boost :: asio, vẫn chưa rõ khi nào tôi cần sử dụng asio :: strand. Giả sử rằng tôi có một chủ đề bằng cách sử dụng io_service là nó sau đó an toàn để viết trên một ổ cắm như sau?Khi nào tôi phải sử dụng boost :: asio: strand

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; 
    } 
    } 
} 

Trường hợp nhiều chủ đề gọi Connection :: write (..) hoặc tôi có phải sử dụng asio :: strand không?

Trả lời

17

Câu trả lời ngắn gọn: không, bạn không phải sử dụng strand trong trường hợp này.

Được đơn giản hóa rộng rãi, một io_service chứa danh sách các đối tượng hàm (trình xử lý). Người xử lý được đưa vào danh sách khi post() được gọi trên dịch vụ. ví dụ. bất cứ khi nào một hoạt động không đồng bộ hoàn thành, trình xử lý và các đối số của nó được đưa vào danh sách. io_service::run() thực thi một trình xử lý sau một trình xử lý khác. Vì vậy, nếu chỉ có một chủ đề gọi run() như trong trường hợp của bạn, không có sự cố đồng bộ hóa và không cần strand giây.
Chỉ khi có nhiều chủ đề gọi run() trên cùng một io_service, nhiều trình xử lý sẽ được thực hiện cùng một lúc, trong chuỗi N đến tối đa N trình xử lý đồng thời. Nếu đó là một vấn đề, ví dụ: nếu có thể có hai trình xử lý trong hàng đợi cùng lúc truy cập cùng một đối tượng, bạn cần strand.
Bạn có thể xem strand như một loại khóa cho một nhóm người xử lý. Nếu một chuỗi thực hiện một trình xử lý được liên kết với một strand, thì strand bị khóa và nó được giải phóng sau khi trình xử lý được thực hiện. Bất kỳ chủ đề nào khác chỉ có thể thực thi các trình xử lý không được liên kết với một khóa strand bị khóa.

Chú ý: lời giải thích này có thể quá đơn giản và về mặt kỹ thuật không chính xác, nhưng nó mang lại một khái niệm cơ bản về những gì xảy ra trong io_service và của strand s.

2

Gọi io_service::run() từ chỉ một chuỗi sẽ khiến tất cả trình xử lý sự kiện thực thi trong chuỗi, bất kể số lượng chuỗi đang gọi Connection::write(...). Do đó, không thể thực hiện đồng thời các trình xử lý, nó sẽ an toàn. Tài liệu đề cập đến điều này như là một implicit strand.

Mặt khác, nếu nhiều luồng đang gọi io_service::run(), thì một sợi sẽ trở nên cần thiết. Câu trả lời This bao gồm các chuỗi chi tiết hơn.

Các vấn đề liên quan