Хиредис, либерав и буст - PullRequest
3 голосов
/ 23 декабря 2011

Попытка написать простой клиент Redis с использованием библиотек hiredis и libev. Все идет хорошо, кроме остановки цикла обработки событий - m_thread.join () просто застрял. Перемещение всего инициализирующего материала во вновь созданный поток ничего не делает.

Вот часть моего кода:


    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) {

    }

Ответы [ 2 ]

0 голосов
/ 20 июля 2014

Если вы подразумеваете ev_run для своего boost::thread, вот что вы можете сделать:

  1. Настройка ev_async

  2. При обратном вызове ev_async вызов ev_break.

  3. Звоните ev_async_send с RedisSubscriber::Stop(). ev_async наблюдатели являются поточно-ориентированными - для синхронизации между потоками используются барьеры памяти.

Это приведет к остановке цикла событий, и m_thread.join() вернется.

0 голосов
/ 27 января 2012

Кажется, вы используете boost::thread() неправильно.Например, ev_loop - это тип, а не функция.

...