Boost 라이브러리는 1.53 버전부터 코루틴이 정식으로 포함되었다. Boost 라이브러리 1.54 버전의 Asio에서는 코루틴을 Asio에서도 사용할 수 있게 되었다.

Asio에서 코루틴을 사용하기 위해서는 boost:asio::spawn을 사용한다.

 

Asio에서 비동기 I/O 함수를 사용할 때는 언제나 Asio의 비동기 함수를 호출하고, 이때 완료 함수를 등록 한다. 그리고 완료 함수가 호출에 의해 작업의 완료를 알게 된다.



boost::asio::spawn을 사용하면 코루틴에 의해 비동기 함수를 호출하면 호출한 곳으로 제어권을 넘긴 후 비동기 작업이 완료하면 비동기 함수 호출 이후 부분에 복귀하여 남은 작업을 처리한다.

아래는 boost::asio::spawn을 사용하여 비동기로 데이터를 보내는 코드이다.


 


< boost::asio::spawn을 사용하여 비동기로 데이터 보내기 >

 

코루틴을 사용해본 경험이 없다면 아마 위의 코드만으로는 잘 이해가 안될 것이다. 그러니 기존의 Chatting 서버를 boost::asio::spawn 사용 버전으로 만든 'ChattingTCPServer_spawn' 프로젝트를 꼭 보고 실행까지 해보기 바란다. boost::asio::spawn을 사용해서 코드가 이전에 비해서 줄어들어서 어렵지 않게 이해할 수 있을 것이다.


ChattingTCPServer_spawn.zip


 

 

<참조>

코루틴(coroutine) 관련 자료

http://devnote.tistory.com/223

 

Boost 라이브러리의 코루틴에 관한 글

C++에서도 coroutine & yield  http://gamedevforever.com/209

다시 한번 C++에서도 coroutin   http://www.gamedevforever.com/289

</참조>

 

<참조>

Boost 라이브러리의 asio::spawn 관련 예제 코드

http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/example/cpp11/spawn/

</참조>

 

저작자 표시
신고
by 흥배 2014.07.07 08:00

packaged_task를 사용하면 병렬 프로그래밍 패턴의 task 패턴과 같이 Asio에서 백그라운드 작업을 처리할 수 있다.





< ioservice.post packaged_task 사용하기 >

 

완전한 코드는 'io_service_post_packaged_task' 프로젝트를 참조하기 바란다.


io_service_post_packaged_task.zip


 

저작자 표시
신고
by 흥배 2014.07.03 08:00

future를 사용하면 비동기 IO 처리의 결과 값을 얻을 수 있다.

아래의 코드는 future를 사용하여 UDP로 보내기와 받기를 하고 있다. future를 사용하고 있어서 비동기 완료 함수를 지정하지 않아도 된다.




( 완전한 코드는 'AsynchronousUDPClient_future' 프로젝트에 있다. )


AsynchronousUDPClient_future.zip


저작자 표시
신고
by 흥배 2014.06.30 08:00

#include <iostream>

#include <string>

#include <boost/variant.hpp>


struct var_printer : boost::static_visitor<void> {

void operator()(int x) const

{

std::cout << x << std::endl;

}


void operator()(std::string& s) const

{

std::cout << s << std::endl;

}


void operator()(double x) const

{

std::cout << x << std::endl;

}

};


int main()

{

std::cout << "저장" << std::endl;

{

boost::variant<int, std::string, double> v;


// 빈 상태

std::cout << v.which() << std::endl;


v = 1; // int 타입의 값 저장

std::cout << v.which() << std::endl;


v = 3.14; // double 타입의 값 저장

std::cout << v.which() << std::endl;

}


std::cout << "타입 판정" << std::endl;

{

boost::variant<int, std::string, double> v;


v = 1; // int 타입의 값 저장

if (v.type() == typeid(int)) {

std::cout << "int" << std::endl;

}


v = 3.14; // double 타입의 값 저장

if (v.type() == typeid(double)) {

std::cout << "double" << std::endl;

}

}


std::cout << "값 얻기" << std::endl;

{

boost::variant<int, std::string, double> v;

v = 1;


// 참조

try {

int& x = boost::get<int>(v);

std::cout << x << std::endl;

}

catch (boost::bad_get& e) {

std::cout << e.what() << std::endl;

}


// 포인터

if (int* x = boost::get<int>(&v)) {

std::cout << *x << std::endl;

}

else {

std::cout << "int 값은 저장 되어 있지 않다." << std::endl;

}

}


std::cout << "값 비우기" << std::endl;

{

boost::variant<boost::blank, int, std::string> v = boost::blank();

v = 3;


v = boost::blank();


if (v.type() == typeid(boost::blank)) {

std::cout << "blank" << std::endl;

}

else {

std::cout << "no blank" << std::endl;

}

}


std::cout << "타입에 맞는 함수 호출하기" << std::endl;

{

// int, string, double

boost::variant<int, std::string, double> v;


v = 3; // int

boost::apply_visitor(var_printer(), v); // visitor으로 타입에 맞는 처리를 한다.


v = "hello"; // string

boost::apply_visitor(var_printer(), v);

}



return 0;

}

// 출처: https://sites.google.com/site/boostjp/tips/variant

저작자 표시
신고
by 흥배 2014.06.18 08:00

복수의 함수를 하나의 함수 오브젝트로 모아서 사용한다.


#include <boost/functional/overloaded_function.hpp>

#include <boost/lexical_cast.hpp>

#include <string>

#include <iostream>



std::string to_string(int n)

{

return boost::lexical_cast<std::string>(n);

}


int to_int(std::string str)

{

return boost::lexical_cast<int>(str);

}



int main()

{

boost::overloaded_function<

std::string(int),

int(std::string)

> multi(&to_string, &to_int);


// 함수 오버라이드와 같이 인수의 타입에 따라서 호출 함수가 정해진다.

std::cout << multi(10) + "-mami" << std::endl;

std::cout << multi("42") * 2 << std::endl;


return 0;

}

// 출처: http://d.hatena.ne.jp/osyo-manga/20140213/1392299962

저작자 표시
신고
by 흥배 2014.06.10 08:00

Pre_defined Compiler Macros 프로젝트에서 모아 놓은 매크로로 C++ 컴파일 환경이나 타겟 환경(OS) 정보를 얻을 수 있다.

Boost 1.55 에서 추가 

  http://www.boost.org/doc/libs/1_55_0/libs/predef/doc/html/index.html 



#include <boost/config.hpp>

#include <boost/predef.h>

#include <iostream>


int main()

{

std::cout << BOOST_COMPILER << std::endl;


#if BOOST_OS_WINDOWS

std::cout << "OS is Windows." << std::endl;

#else

std::cout << "OS is not Windows." << std::endl;

#endif


#if BOOST_COMP_CLANG

std::cout << "Compiler is Clang." << std::endl;

#elif BOOST_COMP_MSVC

std::cout << "Compiler is MSVC." << std::endl;

#else

std::cout << "Compiler is unknow." << std::endl;

#endif



#if BOOST_COMP_MSVC && BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(12, 0, 0)

std::cout << "VC 12" << std::endl;

#elif BOOST_COMP_MSVC && BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(13, 0, 0)

std::cout << "VC 13" << std::endl;

#endif


return 0;

}

// 출처: http://d.hatena.ne.jp/osyo-manga/20131213/1386933884


저작자 표시
신고
by 흥배 2014.06.05 08:00

범용적인 unique한 식별자.

16바이트로 표시하는 유니크한 값을 생성할 수 있다.




저작자 표시
신고
by 흥배 2014.06.02 08:00

Pool

적당한 메모리를 처음부터 확보하고, 그기에서 적절한 메모리를 할당 받는다.

고속으로 메모리를 할당할 수 있다.

그러나 사용할 수 있는 곳이 한정되어 있다.

대량의 작은 오브젝트를 관리해야 하는 경우에 아주 좋다.

게임의 오브젝트 관리나 메모리 제어가 아주 중요한 곳에서 주로 사용한다.



오브젝트와 싱글톤

적당한 메모리를 처음부터 확보하고, 그기에서 적절한 메모리를 할당 받는다.

고속으로 메모리를 할당할 수 있다.

그러나 사용할 수 있는 곳이 한정되어 있다.

대량의 작은 오브젝트를 관리해야 하는 경우에 아주 좋다.

게임의 오브젝트 관리나 메모리 제어가 아주 중요한 곳에서 주로 사용한다.



오브젝트 풀

struct Abc

{

Abc()  { static int no=0; cout << "Abc() :" << (m_no=++no) << endl; }

~Abc() { cout << "~Abc():" << m_no << endl; }

int m_no;

};


boost::object_pool<Abc> p;

Abc* x = p.construct();

Abc* y = p.construct();

Abc* z = p.construct();

p.destroy(y);// 명시적으로 파괴자 호출



싱글톤 풀

// sizeof(int) 바이트 전용 할당자

boost::pool<> p( sizeof(int) );

int* x = (int*)p.malloc();

int* y = (int*)p.malloc();

int* z = (int*)p.malloc();

*x = 10;

p.free(z); // 명시적으로 free


저작자 표시
신고
by 흥배 2014.05.30 08:00

날짜 계산 라이브러리.

Gregorial을 사용한다.



월의 마지막 날

#include <iostream>

#include <boost/date_time/gregorian/gregorian.hpp>


int main()

{

    using namespace boost::gregorian;

  

    const int day = gregorian_calendar::end_of_month_day(2011, 2);

    std::cout << day << std::endl;

}

출처: https://sites.google.com/site/boostjp/tips/date_time



날짜 더하기/빼기

년의 가감산에는 years 타입,  월의 가감산에는 months 타입, 날의 가감산에는 days 타입을 사용한다.

#include <iostream>

#include <boost/date_time/gregorian/gregorian.hpp>


using namespace boost::gregorian;


int main()

{

    const date d1(2011, Apr, 1);

    const date d2 = d1 + months(1) - days(1);


    std::cout << to_simple_string(d2) << std::endl;

}

출처: https://sites.google.com/site/boostjp/tips/date_time



UTL <-> LOCAL

#include <iostream>


#include <boost/date_time.hpp>

#include <boost/date_time/c_local_time_adjustor.hpp>

#include <boost/date_time/local_time_adjustor.hpp>


int main(const int argc, const char * const argv[]) 

{

using namespace boost;


posix_time::ptime now = posix_time::second_clock::universal_time();


// utc to local 1

date_time::c_local_adjustor<posix_time::ptime> adj1;

posix_time::ptime t1 = adj1.utc_to_local(now);


// utc to local 2

date_time::local_adjustor<posix_time::ptime, 9, posix_time::no_dst> adj2;

posix_time::ptime t2 = adj2.utc_to_local(now);


// local to utc

posix_time::ptime t3 = adj2.local_to_utc(t2);


// out

std::cout << now << std::endl;

std::cout << t1 << std::endl;

std::cout << t2 << std::endl;

std::cout << t3 << std::endl;


return 0;

}



저작자 표시
신고
by 흥배 2014.05.27 08:00

데이터 전송 등이 올바르게 되었는지를 검사하기 위한 방법으로 CRC(Cyclic Redundancy Check) 번호라고 부르는 값을 폭 넓게 사용하고 있다.

Boost.Crc 라이브러리는 비트 열에서 CRC 값을 계산하기 위한 라이브러리이다.







crc_01.zip



저작자 표시
신고
by 흥배 2014.05.20 08:00
| 1 2 3 4 5 ··· 7 |

티스토리 툴바