[Boost] ASIO學習筆記:bind and ASIO

posted in: ASIO, boost, C/C++程式設計 | 0

boost::bind的功用,主要是將function變成function object(functor)來當成參數傳送,其目的,最主要是用來實現系統callback的功能。以下為一個簡單的小程式:

#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
boost::asio::io_service io_service;

void WorkerThread(int x){     
    std::cout < < "Thread Start:" << x << endl;      
    io_service.run();      
    std::cout << "Thread Finish:" << x << endl;
}

int main( int argc, char * argv[] ){  
    boost::shared_ptr< boost::asio::io_service::work > work( new boost::asio::io_service::work( io_service ));      
    std::cout < < "Press [Enter] to exit." << std::endl;      
    boost::thread_group worker_threads;      
    for( int x = 0; x < 4; ++x )        {       
        worker_threads.create_thread( boost::bind( &WorkerThread, x ));    
    }      
    std::cin.get();     
    io_service.stop();
    worker_threads.join_all();       
    system("pause");
    return 0;
}

 

 

boost::bind( &WorkerThread, x )中的x為我們在callback function中所指定要傳送進入的參數,二邊的個數只要一致就能夠順利的傳入。

下面的列子是用來bind一個class中的function menber:

#include <iostream>
#include <boost/bind.hpp>
class MyClass{
public:    
void F3( int i, float f ){       
    std::cout < < "i: " << i << std::endl;          
    std::cout << "f: " << f << std::endl;      
    }
};
int main( int argc, char * argv[] ){   
    MyClass c;      
    boost::bind( &MyClass::F3, &c, 42, 3.14f )();    
    system("pause");
    return 0;
}

只是,當我們使用bind要將io_service當作參數傳入給callback function的時候,會出現以下這個訊息:error C2248: ‘boost::noncopyable_::noncopyable::noncopyable’。這是由於io_service是不允許進行複制,這時候可以用以下二種方法來達成目的:一、傳址 二、使用smart point機制

方法一 傳址:

#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <iostream>
using namespace std;

void WorkerThread(boost::asio::io_service* io_service, int x){     
    std::cout < < "Thread Start:" << x << endl;      
    io_service->run();      
    std::cout < < "Thread Finish:" << x << endl;
}

int main( int argc, char * argv[] ){  
    boost::asio::io_service io_service;
    boost::shared_ptr< boost::asio::io_service::work > work( new boost::asio::io_service::work( io_service ));      
    std::cout < < "Press [Enter] to exit." << std::endl;      
    boost::thread_group worker_threads;      
    for( int x = 0; x < 4; ++x )        {       
        worker_threads.create_thread( boost::bind( &WorkerThread, &io_service, x ));    
    }      
    std::cin.get();     
    io_service.stop();
    worker_threads.join_all();       
    system("pause");
    return 0;
}

方法二 smart pointer:

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

using namespace std;

void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service, int x ){     
    std::cout << "Thread Start:" << x << endl;     
    io_service->run();      
    std::cout << "Thread Finish:" << x << endl ;
}


int main( int argc, char * argv[] ){    
    boost::shared_ptr< boost::asio::io_service > io_service(      
        new boost::asio::io_service        );       
    boost::shared_ptr< boost::asio::io_service::work > work(         
      new boost::asio::io_service::work( *io_service )        );  
    std::cout << "Press [Enter] to exit." << std::endl;    
    boost::thread_group worker_threads;      
    for( int x = 0; x < 4; ++x )        {             
        worker_threads.create_thread( boost::bind( &WorkerThread, io_service, x ) );   
    }       
    std::cin.get();     
    io_service->stop();    
    worker_threads.join_all();       
    return 0;
}



dorgon

dorgon

職業:LV3遊戲軟體工程師 為了追尋小時候玩遊戲的感動,而一頭栽入遊戲業界。 本來以撰寫遊戲劇本為主要志向,但回過神來才發現已經踏入程序猿的不歸路。 專長為client端跨平台遊戲開發架構與自動建置流程,主要使用引擎為cocos2d-x與UnrealEngine4。

More Posts - Website

Follow Me:
FacebookLinkedIn

有什麼想法嗎?請發表你的看法