1. 程式人生 > >asio的post和run函式

asio的post和run函式

受到avplayer群裡的aver的影響,我也開始對asio感興趣了,本著啥都要參和參和的思想,我也來搞一把asio,學到點東西就記錄一下,由於是初學,可能會有很多錯誤,各位看官如果發現問題請不吝賜教或者盡情開噴。

一般來說大多數人使用asio都是用它來做非同步的網路庫來使用,但是asio本質上是一個通用的非同步庫,並不是只能用來做網路通訊,所以我不打算一上來就搞網路方面的東西。

非同步的概念其實很簡單,你把要做的事情告訴可以完成這件事的庫或者作業系統,由庫或者系統幫你完成並通知你,在此期間你可以做其他的操作。

asio 非同步的核心其實就是一個boost::asio::io_service類,可以想象成是一個發動機,你有事情要做,就扔給他,他就幫你完成,你把事情告 訴他之後並不需要一直等待事情的完成,而是可以馬上去做其他的事情。其中類的成員函式post()就是提交要做的事情,成員函式run()就是啟動發動機。就像下面的程式碼:

#include <boost/asio.hpp>
#include <iostream>

void foo()
{
    std::cout << "Hello asio!" << std::endl;
}

int main(int argc, char* argv[])
{
    boost::asio::io_service ios;
    ios.post(foo);

    std::cout << "after post" << std::endl;

    ios.run();
    return
0; }

執行結果:

20140218101133.jpg

可以看到提交了“任務”之後並沒有馬上執行,而是等到了run的時候才執行的。看起來很簡單是吧,那就再加點東西,假設foo函式式是統提供的,但是提供了個回撥函式在完成後會進行呼叫來通知我們,程式碼就變成這樣了:

#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
#include <functional>

typedef std::function<void()> handler_t;
void foo(handler_t handler)
{
    std
::cout << "Hello asio!" << std::endl; handler(); } void handler_fun() { std::cout << "mission complete!" << std::endl; } int main(int argc, char* argv[]) { boost::asio::io_service ios; ios.post(boost::bind(foo, handler_fun)); std::cout << "after post" << std::endl; ios.run(); return 0; }

執行結果:

20140218101507.jpg

其實asio的網路操作函式也與此類似,foo是執行指定任務的函式,執行完後就呼叫我們的handler來通知我們,這樣我們就可以不用一直等待操作完成,立即去執行其他的任務。

這樣做還有一個優點是可以在多個執行緒上執行run函式,可以更充分利用多核的效能,“任務”並不是在提交任務的執行緒中執行的,而是在執行run的執行緒中執行 的,如果多個執行緒同時執行同一個io_service物件的run函式,則會每個執行緒都去從這個service的“任務列表”裡面獲取任務去執行。

#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <boost/thread.hpp>
#include <iostream>

void foo()
{
    std::cout << "Hello asio! thread ID:" << boost::this_thread::get_id() << std::endl;
}

int main(int argc, char* argv[])
{
    boost::asio::io_service ios;

    for (int i = 0; i < 1000; ++i)
    {
        ios.post(foo);
    }

    boost::thread_group thrds;
    for (int i = 0; i < 4; ++i)
    {
        thrds.create_thread(boost::bind(&boost::asio::io_service::run, &ios));
    }

    thrds.join_all();
    return 0;
}

執行結果如下:
20140218101814.jpg

為了簡單起見沒有加鎖,所以會有換行不正常的現象,希望大家不要介意。。。但是還是很容易看出這些程式碼是在不同的執行緒中執行的。

本文轉自:往事如風