asio學習筆記8——stackfull coroutine
blog中的文章地址:http://www.godebug.org/index.php/archives/126/
今天沒事可幹,就再寫一篇吧啊哈哈哈 這個spawn是boost 1.54中的asio新增加的東西,我目前用的boost是1.56,如果不能用以下程式碼請更新boost.... 其實有了之前介紹的asio中的stackless coroutine和stackfull的boost.coroutine,這裡也就沒啥原理性的東西介紹了,asio到底怎麼封裝的我也沒看明白,不過只要好用就行了。簡單說一下幾個類和函式的作用就可以了,剩下的太簡單了,簡直就跟迴歸了同步的網路程式設計一個樣了。 還是直接上程式碼:
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <memory>
#include <functional>
#include <iostream>
class session : public std::enable_shared_from_this < session >
{
public:
explicit session(boost::asio::io_service& io_service)
: strand_(io_service), socket_(io_service)
{
}
boost::asio::ip::tcp::socket& socket()
{
return socket_;
}
void go()
{
boost::asio::spawn(strand_,
std::bind(&session::echo,
shared_from_this(), std::placeholders::_1));
}
private:
void echo(boost::asio::yield_context yield)
{
char data[128];
for (;;)
{
std::size_t n = socket_.async_read_some(boost::asio::buffer(data), yield);
boost::asio::async_write(socket_, boost::asio::buffer(data, n), yield);
}
}
boost::asio::io_service::strand strand_;
boost::asio::ip::tcp::socket socket_;
};
void do_accept(boost::asio::io_service& io_service,
unsigned short port, boost::asio::yield_context yield)
{
boost::asio::ip::tcp::acceptor acceptor(
io_service,
boost::asio::ip::tcp::endpoint(
boost::asio::ip::tcp::v4(), port));
for (;;)
{
boost::system::error_code ec;
std::shared_ptr<session> new_session(std::make_shared<session>(io_service));
acceptor.async_accept(new_session->socket(), yield[ec]);
if (!ec)
{
new_session->go();
}
}
}
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
boost::asio::spawn(io_service,
std::bind(do_accept,
std::ref(io_service), 8888, std::placeholders::_1));
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
把asio的example\cpp03\spawn中的例子稍微修改了下。簡單解釋下,boost::asio::spawn就是開啟了一個stackfull的coroutine,這個函式需要一個回撥函式(比如說do_accept),然後會傳一個boost::asio::yield_context給這個函式,只要用這個yield_context作為handle來呼叫asio的非同步函式,就可以把這些函式程式設計“同步”的。不過這個“同步”是加引號的,雖然這個名叫非同步,但是是同步的操作在沒有完成之前是不會返回的,但是在內部會繼續執行其他的非同步操作,並不會真的阻塞。於是我們現在就同時有了一部和同步的優勢,既不會因為同步喪失效能,也不會像原來的非同步那樣一個接一個的回撥,寫的都要吐了。boost::asio::io_service::strand我理解的就是總是把io_service傳來傳去不方便,是用來代替io_service給spawn開coroutine的。
回想一下之前用asio非同步要迴圈幹某件事的一般做法,至少需要單獨定義兩個函式,一個用來發起非同步操作,比如說呼叫boost::asio::async_read,第二個函式用來做事件完成的handle,然後在handle中再次呼叫發起非同步操作的那個函式,這樣就構成了一個迴圈。但是現在我們只需要用c++本身的迴圈語句即可搞定,就像上面的do_accept。
另外就是1.當一個非同步讀取/寫入函式用了yield當handler,它的返回值一般是讀取或者寫入的位元組數;2.yield過載了[],可以接受一個boost::system::error_code作引數,返回出錯資訊的。如果不傳入這個error_code,函式會把他當異常丟擲來,這些可以很明顯的從示例程式碼中看出來。
over
相關文章
- stackless/stackfull coroutine 筆記筆記
- boost.coroutine學習筆記筆記
- CCNA學習筆記8筆記
- Android學習筆記(8)Android筆記
- G01學習筆記-8筆記
- Tensorflow學習筆記No.8筆記
- k8s學習筆記K8S筆記
- JDK8 新特性學習筆記JDK筆記
- oracle學習筆記8: 分析函式Oracle筆記函式
- angular學習筆記(三十)-指令(8)-scopeAngular筆記
- DG學習筆記(8)_Switchover and Failover筆記AI
- 強化學習-學習筆記8 | Q-learning強化學習筆記
- Flutter學習筆記(8)--Dart物件導向Flutter筆記Dart物件
- Laravel8學習筆記-日誌元件Laravel筆記元件
- numpy的學習筆記\pandas學習筆記筆記
- Pytest學習筆記8-引數化筆記
- Python學習筆記8——列表、字典、元組Python筆記
- Java學習筆記8-資料型別Java筆記資料型別
- IT學習筆記筆記
- 學習筆記筆記
- Angular6學習筆記8: 服務(Service)(1)Angular筆記
- python學習筆記:第8天 檔案操作Python筆記
- Jdk8 新日期工具類 Api 學習筆記JDKAPI筆記
- Laravel8學習筆記01 - 目錄結構Laravel筆記
- .NET 6學習筆記(8)生成自簽證書筆記
- Tensorflow學習筆記(8)——input_data.py解析筆記
- win8 學習筆記二 輸出日誌筆記
- surfer 8 scripter 學習筆記(1)指令碼物件模型筆記指令碼物件模型
- MYSQL學習筆記8: DQL分組查詢(group by)MySql筆記
- 【學習筆記】數學筆記
- 《JAVA學習指南》學習筆記Java筆記
- Elasticsearch學習筆記Elasticsearch筆記
- Scala學習筆記筆記
- MySql學習筆記MySql筆記
- jQuery 學習筆記jQuery筆記
- react學習筆記React筆記
- 學習筆記(4.3)筆記
- 學習筆記(4.4)筆記