2011-12-23 3 views
3

hiredis 및 libev 라이브러리를 사용하여 간단한 Redis 클라이언트를 작성하려고합니다. 이벤트 루프 - m_thread.join()이 멈추었을 때를 제외하고는 모든 것이 잘되고 있습니다. 초기화 된 내용을 새로 생성 된 스레드로 옮기는 작업은 아무 것도하지 않습니다.Hiredis, libev 및 boost : threads

 

    void RedisSubscriber::Start() { 
     m_redis = redisAsyncConnect(m_addr.c_str(),m_port); 
     m_redis->data = (void*)this; 

     m_loop = ev_loop_new(EVFLAG_NOINOTIFY); 
     redisLibevAttach(m_loop, m_redis); 
     redisAsyncSetConnectCallback(m_redis,connectCallback); 
     redisAsyncSetDisconnectCallback(m_redis,disconnectCallback); 
     redisAsyncCommand(m_redis, subscribeCallback, NULL, "SUBSCRIBE %s", m_channel.c_str()); 

     m_thread = boost::thread(ev_loop,m_loop,0); 
    } 

    void RedisSubscriber::Stop() { 
     redisAsyncFree(m_redis); 
     m_thread.join(); 
     m_redis = 0; 
    } 

    void RedisSubscriber::connectCallback(const redisAsyncContext *c) { 

    } 

    void RedisSubscriber::disconnectCallback(const redisAsyncContext *c, int status) { 
     RedisSubscriber* r = (RedisSubscriber*)(c->data); 
     ev_unloop(r->m_loop,EVUNLOOP_ALL); 
    } 

    void RedisSubscriber::subscribeCallback(redisAsyncContext *c, void *r, void *privdata) { 

    } 

답변

0

boost::thread()의 사용이 잘못된 것 같다 여기

내 코드의 일부입니다. 하나의 경우, ev_loop은 유형이 아니라 기능이 아닙니다.

0

여기에 당신이 할 수있는 무엇, 당신이 당신의 boost::thread에 대한 ev_run을 의미한다고 가정 :

  1. 설정 ev_async 전화 ev_break의 콜백의 ev_async

  2. .

  3. ev_async_send에서 RedisSubscriber::Stop()으로 전화하십시오. ev_async와 쳐는 스레드로부터 안전합니다. 스레드간에 동기화하는 데 메모리 장벽을 사용합니다.

이렇게하면 이벤트 루프가 중지되고 m_thread.join()이 반환됩니다.