Thinking Different




boost asio 네트워크 프로그래밍을 배우면서 io_services.run() 함수 blocking을 통제(?) 하기 위해서 수단을 찾다가 몇가지 방법을 기술하도록 한다.


(원래의 목적은 서버를 실행한 다음 getchar() 입력을 대기하는동안 계속 서버는 구동되고, 키보드의 입력이 있을 경우 stop() 콜을 하여 서버가 종료되도록 하는것이 목적이었다.)


if( 서버.시작() == true) {

       getchar();

       서버.종료();

}

대략 이런 코드 구조....



boost asio 의 io_services.run() 함수는 구동중인 스레드에서 blocking 되는 함수로써 이를 non-blocking 함수처럼 사용하기 위해서 열심히 구글링해서 찾은 아래와 같이 키보드 입력에 대한 인터럽트를 이용하여 방법을 구현한 것이 1번째이다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "stdafx.h"
#include "../ServerLibrary/MemLeakDetector.h"
 
const int MAX_SESSION_COUNT = 5;
 
// 콘솔 컨트롤 핸들러가 호출할 함수
boost::function0<void> console_ctrl_function;
 
// 콘솔의 컨트롤 헨들러
BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
{
    switch (ctrl_type)
    {
    case CTRL_C_EVENT:
    case CTRL_BREAK_EVENT:
    case CTRL_CLOSE_EVENT:
    case CTRL_SHUTDOWN_EVENT:
        // 콘솔에서 다음 컨트롤 타입 이벤트가 생기면 호출된다.
        console_ctrl_function();
        return TRUE;
    default:
        return FALSE;
    }
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    GameServer server(MAX_SESSION_COUNT);
 
    console_ctrl_function = boost::bind(&GameServer::Stop, &server);
    SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
    // GameServer::Stop 함수내에서 io_services.stop(); 호출
 
    server.Start();
    // Start 함수 내에서 io_services.run(); 호출  (block 됨)
 
    std::cout << "네트웍 접속 종료" << std::endl;
 
    return 0;
}



두번째 방법은 boost::asio::io_service::work을 활용한 방법으로 io_services.run() 함수를 별도의 스레드에 올려서 실행되도록 하면 non-blocking 하게 사용 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 선언부분
boost::shared_ptr<boost::asio::io_service::work> async_work;
boost::thread_group async_thread;
 
// Start() 내부
// .....
async_work.reset(new boost::asio::io_service::work(io_service));
async_thread.create_thread(boost::bind(&boost::asio::io_service::run, &io_service));
// .....
 
// Stop() 내부
// .....
async_work.reset();
io_service.stop();
async_thread.join_all();
// .....
 
 
// main 함수
const int MAX_SESSION_COUNT = 5;
 
int _tmain(int argc, _TCHAR* argv[])
{
    GameServer server(MAX_SESSION_COUNT);
 
    if (server.Start() == true)
    {
        getchar();
        server.Stop();
    }
 
    return 0;
}


'프로그래밍 언어 > boost' 카테고리의 다른 글

Boost.Swap  (0) 2015.05.06
Boost.Array  (0) 2015.05.04
Boost.Tuple & std::pair  (0) 2015.05.03
Boost.Function  (0) 2015.05.01
Boost.Bind  (0) 2015.04.30