asio C++ library核心理念和功能(四)

1.2.10 處理程序跟蹤
為了幫助調(diào)試異步程序,Asio提供了對(duì)處理程序跟蹤的支持瞬逊。 通過定義ASIO_ENABLE_HANDLER_TRACKING啟用時(shí),Asio將調(diào)試輸出寫入標(biāo)準(zhǔn)錯(cuò)誤流。 輸出記錄異步操作及其處理程序之間的關(guān)系理盆。
此功能在調(diào)試時(shí)非常有用,您需要知道異步操作是如何鏈接在一起的凑阶,或者是哪些待處理的異步操作猿规。 舉例來說,這里是運(yùn)行HTTP Server示例時(shí)的輸出宙橱,處理單個(gè)請(qǐng)求姨俩,然后通過Ctrl + C關(guān)閉:

@asio|1298160085.070638|0*1|signal_set@0x7fff50528f40.async_wait
@asio|1298160085.070888|0*2|socket@0x7fff50528f60.async_accept
@asio|1298160085.070913|0|resolver@0x7fff50528e28.cancel
@asio|1298160118.075438|>2|ec=asio.system:0
@asio|1298160118.075472|2*3|socket@0xb39048.async_receive
@asio|1298160118.075507|2*4|socket@0x7fff50528f60.async_accept
@asio|1298160118.075527|<2|
@asio|1298160118.075540|>3|ec=asio.system:0,bytes_transferred=122
@asio|1298160118.075731|3*5|socket@0xb39048.async_send
@asio|1298160118.075778|<3|
@asio|1298160118.075793|>5|ec=asio.system:0,bytes_transferred=156
@asio|1298160118.075831|5|socket@0xb39048.close
@asio|1298160118.075855|<5|
@asio|1298160122.827317|>1|ec=asio.system:0,signal_number=2
@asio|1298160122.827333|1|socket@0x7fff50528f60.close
@asio|1298160122.827359|<1|
@asio|1298160122.827370|>4|ec=asio.system:125
@asio|1298160122.827378|<4|
@asio|1298160122.827394|0|signal_set@0x7fff50528f40.cancel

Each line is of the form:

<tag>|<timestamp>|<action>|<description>

<tag>始終是@asio,用于標(biāo)識(shí)和提取程序輸出中的處理程序跟蹤消息师郑。
從1970年1月1日UTC開始环葵,<timestamp>是秒和微秒。
<action>采用以下形式之一:

> n程序進(jìn)入處理程序編號(hào)n宝冕。 <description>顯示處理程序的參數(shù)张遭。
<n程序離開處理程序編號(hào)n。
地梨!n由于例外菊卷,程序編號(hào)為n。
?n處理程序編號(hào)n在未被調(diào)用的情況下銷毀宝剖。 任何未完成的異步通常都是這種情況
當(dāng)io_service被銷毀時(shí)的操作的烁。
n * m處理程序編號(hào)n用完成處理程序編號(hào)m創(chuàng)建了一個(gè)新的異步操作。 <description>顯示了異步操作已啟動(dòng)诈闺。
n處理程序編號(hào)n執(zhí)行了其他一些操作渴庆。 <description>顯示了被調(diào)用的函數(shù)。 目前只
記錄close()和cancel()操作,因?yàn)檫@些操作可能會(huì)影響未決異步操作的狀態(tài)襟雷。

當(dāng)<description>顯示同步或異步操作時(shí)刃滓,格式為<object-type> @ <pointer>。<operation>耸弄。 對(duì)于處理程序輸入咧虎,它顯示一個(gè)以逗號(hào)分隔的參數(shù)列表及其值。
如上所示计呈,每個(gè)處理程序都被分配一個(gè)數(shù)字標(biāo)識(shí)符砰诵。 處理程序跟蹤輸出顯示的處理程序編號(hào)為0時(shí),表示該操作是在任何處理程序之外執(zhí)行的捌显。

視覺表示
處理程序跟蹤輸出可以使用包含的handlerviz.pl工具進(jìn)行后處理茁彭,以創(chuàng)建處理程序的可視化表示(需要GraphViz工具點(diǎn))。

1.2.11 無堆棧協(xié)程

協(xié)程類為無堆棧協(xié)程提供支持扶歪。 無堆棧協(xié)程使程序能夠以最小的開銷以同步方式實(shí)現(xiàn)異步邏輯理肺,如以下示例所示:

struct session : asio::coroutine
{
  boost::shared_ptr<tcp::socket> socket_;
  boost::shared_ptr<std::vector<char> > buffer_;
  session(boost::shared_ptr<tcp::socket> socket)
    : socket_(socket),
  buffer_(new std::vector<char>(1024)){ }
  void operator()(asio::error_code ec = asio::error_code(), std::size_t n = 0)
  {
    if (!ec) reenter (this)
     {
        for (;;){
          yield socket_->async_read_some(asio::buffer(*buffer_), *this);
          yield asio::async_write(*socket_, asio::buffer(*buffer_, n), *this);
        }
      }
  }
};

協(xié)程類與偽關(guān)鍵字reenter,yield和fork一起使用善镰。 這些是預(yù)處理器宏妹萨,并且使用類似于Duff's Device的技術(shù)通過switch語句實(shí)現(xiàn)。 協(xié)程類的文檔提供了這些偽關(guān)鍵字的完整描述炫欺。

1.2.12 堆棧協(xié)程

spawn()函數(shù)是運(yùn)行堆棧協(xié)程的高級(jí)包裝器乎完。 它基于Boost.Coroutine庫。 spawn()函數(shù)使程序能夠以同步方式實(shí)現(xiàn)異步邏輯品洛,如以下示例所示:

asio::spawn(my_strand, do_echo);
// ...
void do_echo(asio::yield_context yield)
{
  try
  {
    char data[128];
    for (;;)
    {
      std::size_t length =
      my_socket.async_read_some(
        asio::buffer(data), yield);
        asio::async_write(my_socket,
        asio::buffer(data, length), yield);
    }
  }
  catch (std::exception& e)
  {
    // ...
  }
}

spawn()的第一個(gè)參數(shù)可能是一個(gè)strand囱怕,io_service或完成處理程序。 此參數(shù)確定允許協(xié)程執(zhí)行的上下文毫别。 例如娃弓,服務(wù)器的每個(gè)客戶端對(duì)象可能包含多個(gè)協(xié)程; 它們應(yīng)該全部運(yùn)行在同一條鏈上,以便不需要明確的同步岛宦。
第二個(gè)參數(shù)是一個(gè)帶簽名的函數(shù)對(duì)象:

void coroutine(asio::yield_context yield);

指定要作為協(xié)程的一部分運(yùn)行的代碼台丛。 可以將參數(shù)yield傳遞給異步操作來代替完成處理程序,如下所示:

std::size_t length =
  my_socket.async_read_some(
    asio::buffer(data), yield);

這啟動(dòng)異步操作并暫停協(xié)程砾肺。 當(dāng)異步操作完成時(shí)挽霉,協(xié)程將自動(dòng)恢復(fù)。異步操作的處理程序簽名具有以下形式:

void handler(asio::error_code ec, result_type result);

啟動(dòng)函數(shù)返回result_type变汪。 在上面的async_read_some示例中侠坎,這是size_t。 如果異步操作失敗裙盾,則error_code將轉(zhuǎn)換為system_error異常并拋出实胸。
處理器簽名的形式如下:

void handler(asio::error_code ec);

啟動(dòng)函數(shù)返回void他嫡。 如上所述,錯(cuò)誤作為system_error異常傳遞回協(xié)程庐完。 要從操作中收集error_code钢属,而不是讓它引發(fā)異常,請(qǐng)將輸出變量與yield_context關(guān)聯(lián)起來门躯,如下所示:

asio::error_code ec;
std::size_t length =
  my_socket.async_read_some(
    asio::buffer(data), yield[ec]);

注意:如果spawn()與Handler類型的自定義完成處理程序一起使用淆党,則函數(shù)對(duì)象簽名實(shí)際上是:

void coroutine(asio::basic_yield_context<Handler> yield);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市讶凉,隨后出現(xiàn)的幾起案子染乌,更是在濱河造成了極大的恐慌,老刑警劉巖懂讯,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荷憋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡域醇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蓉媳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來譬挚,“玉大人,你說我怎么就攤上這事酪呻〖跣” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玩荠,是天一觀的道長(zhǎng)漆腌。 經(jīng)常有香客問我,道長(zhǎng)阶冈,這世上最難降的妖魔是什么闷尿? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮女坑,結(jié)果婚禮上填具,老公的妹妹穿的比我還像新娘。我一直安慰自己匆骗,他們只是感情好劳景,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碉就,像睡著了一般盟广。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓮钥,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天筋量,我揣著相機(jī)與錄音烹吵,去河邊找鬼。 笑死毛甲,一個(gè)胖子當(dāng)著我的面吹牛年叮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玻募,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼只损,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了七咧?” 一聲冷哼從身側(cè)響起跃惫,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艾栋,沒想到半個(gè)月后爆存,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝗砾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年先较,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悼粮。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闲勺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扣猫,到底是詐尸還是另有隱情菜循,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布申尤,位于F島的核電站癌幕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏昧穿。R本人自食惡果不足惜勺远,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望时鸵。 院中可真熱鬧谚中,春花似錦、人聲如沸寥枝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽囊拜。三九已至某筐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冠跷,已是汗流浹背南誊。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工身诺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抄囚。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓霉赡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親幔托。 傳聞我的和親對(duì)象是個(gè)殘疾皇子穴亏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容