2012-03-17 2 views
1

내 프로젝트에는 모든 클래스 객체가 특정 객체 기능이 수행되는 무한주기 (while (1)) 내부에 자체 스레드가 있습니다. 그리고 모든 객체가 타이머와 비동기 적으로 기능을 수행하도록 변경하려고합니다.boost :: threads에서 boost :: asio 타이머까지

기본적으로 이것은 무한 루프 스레드와 함께 작동하는 방법이다 :

class obj 
{ 
    public: 
      obj(); 
      ~obj(); 
     //custom functions and variables 
     int x; 
     int obj_action; 
     move(); 
     wait(); 

} 

obj() 
{ 
    obj_action=1; 
    //when constructing object, make its thread with infinite while cycle 
    boost::thread make_thread(boost::bind(&obj::obj_engine,this)); 
} 

void obj::obj_engine() 
{ 
    while(true) 
    { 
     if (obj_action==1){move();} 
     else if (obj_action==2){wait();} 
     Sleep(1); 
    } 
} 

void obj::move() 
{ 
     x++; 
     obj_action==2; 
} 


void obj::wait() 
{ 
     Sleep(5000); 
     obj_action==1; 
} 

이 예와, 생성자, 소멸자, 변수의 부부와 기능의 몇 가지는 OBJ 클래스. 개체 (obj())를 생성 할 때 스레드가 만들어집니다. 스레드는 무한 루프 (while (true))를 갖는 "obj_engine"함수를 포함합니다. 루프에는 두 가지 함수가 있습니다. 1. wait() - 스레드가 5 초 동안 휴면 상태가됩니다. 2. walk() - 간단하게 x + 1 두 함수는 obj_action을 정의하여 끝나면 서로 전환합니다.

이제 구조 및 객체가 비동기 적으로 move() 함수가 수행되고 move() 함수가 수행 된 후 비동기 적으로 wait() 함수가 수행되고 vice versse가 변경됩니다. 그래서 어떤 쓰레드도 사용할 필요가 없습니다.

//constructing 
obj() 
{ 
     asynchronous(walk()); 
} 

walk() 
{ 
    x++ 
    asynchronous(wait()); 
} 

wait() 
{ 
    Sleep(5000); 
    asynchronous(walk()); 
} 

내가 부스트 : ASIO 타이머와 함께, 당신은이 작업을 수행 할 수 있습니다 들었지만, 난 정말 방법을 모르는 :

나는 다음과 같은 결과를 기대. 누군가 어떻게 나를 보여 주면 매우 감사 할 것입니다. 여기

+0

지금 수정 된 초기 소스 코드에서 메모리 누수가 있었기 때문에 제 대답의 업데이트를 확인하십시오. 죄송합니다. – nijansen

답변

2

당신은 이동 : this tutorial shows you how to use an asynchronous timerthis tutorial shows you how to reset your timer : 당신이 필요로하는

#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/bind.hpp> 
#include <iostream> 



class obj { 
public: 
    obj() : x_(0), t_(io_service_, boost::posix_time::seconds(5)) { 
     t_.async_wait(boost::bind(&obj::move, this)); 
     io_service_.run(); 
    } 

    void move() { 
     x_++; 
     std::cout << x_ << std::endl; 
     t_.expires_at(t_.expires_at() + boost::posix_time::seconds(5)); 
     t_.async_wait(boost::bind(&obj::move, this)); 
    } 

private: 
    int x_; 
    boost::asio::io_service io_service_; 
    boost::asio::deadline_timer t_; 
}; 

int main(int, char**) { 
    obj a; 
    while(true); 
} 

기본적으로 모든 것이 ASIO 튜토리얼이 적용됩니다.

업데이트 :

일 내 초기 대신 위의 소스 코드를 사용하십시오 - 각 move 호출은 다른 스레드에서 호출 될 것이며, 잠시 후 응용 프로그램 때문에 충돌 것 때문에 io_service_.run()의 반복 호출에 그것의. 위의 코드는이 문제를 해결하고 이렇게함으로써 wait 함수를 제거합니다.

+0

하지만 더 많은 객체를 추가하려고하면 : obj a; obj b; obj c; 같은 생성자가 초기화를 완료하지 않은 결과를 얻습니다. 나는 모든 객체가 개별적으로 그 기능을 수행하기를 원한다. 이제는 첫 번째 객체를 인쇄한다. x ++ (1,2,3,4,5) 결과는 (111,222,333,444,555)와 같을 것이다. 쓰레드 예제. –

2

nijansen의 예제를 빌려서, 나는 당신이 원하는 것 (내가 생각하는 것)과 더 비슷한 뭔가를 채찍질했습니다.

여기서 중요한 것은 io_service가 모든 개체의 일정 사이에 공유되어야한다는 것입니다. 일반적으로 스레드 당 하나의 io_service가 있지만 더 복잡한 스키마도 사용할 수 있습니다. io_service::run은 io_service (예약 대기 시간 초과 또는 소켓 대기 중)에서 예약 된 작업이있는 한 계속 실행됩니다. 더 이상 예정된 작업이 없으면 간단히 반환됩니다.

은 "활성 객체"(다른 io_services 및 다른 스레드에서 실행중인 경우에도 작동 함)간에 메시지를 보내는 방법으로 사용할 수 있습니다. boost::bind 및 가능한 경우 boost::signals을 볼 수 있습니다.

#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/bind.hpp> 
#include <iostream> 

namespace asio = boost::asio; 

class obj { 
public: 
    obj(asio::io_service& ioSvc) 
     : x_(0), t_(ioSvc) 
    { 
     schedule_in(5); 
    } 

    void schedule_in(int seconds) { 
     t_.expires_from_now(boost::posix_time::seconds(3)); 
     t_.async_wait(boost::bind(&obj::move, this)); 
    } 

    void move() { 
     x_++; 
     std::cout << x_ << std::endl; 
     schedule_in(5); 
    } 

private: 
    int x_; 
    boost::asio::deadline_timer t_; 
}; 

int main(int, char**) { 
    boost::asio::io_service io_service; 
    obj a(io_service); 
    obj b(io_service); 
    obj c(io_service); 
    io_service.run(); 
} 
+0

고맙습니다. 마지막 질문은 다음과 같습니다. 게임 서버의 모든 개체에서 스레드보다 동기 타이머를 사용하는 것이 더 좋습니까? "더 나은"이라고 말하면 효율성, 메모리 사용량이 적고 인기있는 변형이 무엇입니까? –

+1

개체 당 스레드를 유지하지 않을 것입니다. 부분적으로 많은 객체 (수천 또는 수천)에 대해 오버 헤드, 동기화가 실질적인 문제가됩니다. 또한 몇몇 객체의 경우에도 스레드 간의 동기화 및 통신이 매우 까다로워 질 수 있습니다. 실제로 서버를 작성하는 경우 비동기 IO 모델이 반드시 필요합니다. 확장 성이 뛰어나고 "이벤트"처리를위한 적절한 모델입니다. 서버가 CPU를 많이 사용하는 작업을 수행하는 경우 io_service를 여러 스레드로 분할하거나 백그라운드 스레드 풀을 계속 두꺼운 상태로 유지할 수 있습니다. – Rawler

관련 문제