redis 多线程 取消订阅 频道

//问题1,调用exit 返回0,但无法立刻退出dispatch,(必须等待收到新的channel推送才能退出)
ret=event_base_loopexit(base,NULL);

//问题2,调用exit 返回0,调用loopbreak,始终返回-1,无法退出dispath(必须等待收到新的channel推送才能退出)
ret=event_base_loopexit(base,NULL);
ret=event_base_loopbreak(base);

//解决方法,在调用 event_base_new()前使用evthread_use_pthreads(),并且调用event_base_loopbreak退出,

evthread_use_pthreads();//不加此句,多线程下loopbreak返回-1
base = event_base_new();
......
ret=event_base_loopexit(base,NULL);
ret=event_base_loopbreak(base);//不加此句,如果没有新消息推送,无法退出dispatch
#include "hiredis.h"
#include "stdio.h"
#include "constdefine.h"
#include <string.h>
#include <string>
#include <pthread.h>
#include <event2/thread.h>
#include <unistd.h>//
//#include <stdio.h>
#include <stdlib.h>
//#include <string.h>
#include <signal.h>
#include "hiredis/hiredis.h"
#include "hiredis/async.h"
#include "hiredis/adapters/libevent.h"

 

    redisContext * m_Context;
    int  m_Port;
    char m_serverIP[100];

 

struct event_base *base;
redisAsyncContext *c;
bool eventFlag;


void onMessage(redisAsyncContext *c, void *reply, void *privdata)
{
    redisReply *r = (redisReply *) reply;
    if (reply == NULL) return;

    if (r->type == REDIS_REPLY_ARRAY) 
    {
        for (unsigned int j = 0; j < r->elements; j++) 
        {
            printf("%u) %s\n", j, r->element[j]->str);
        }
    }
}
void * test_sub(void * args)
{
    
    
   
    event_base_dispatch(base);
    //int count = 0;
    //while(eventFlag)
    //{
    //    event_base_loop(base, EVLOOP_ONCE);
    //    //if (count++ % 1000 == 0)
    //    {
    //    printf("event_base_loop %d\n", count++);
    //    }
    //    usleep(1000);
   
    //}
    //redisAsyncDisconnect(c);
    //redisAsyncFree(c);
    printf("exit sub\n");
    return 0;
}

 


bool ThreadRun(uint64_t &handle)
{
    pthread_t tids;
    evthread_use_pthreads();
    base = event_base_new();
    eventFlag = true;
    if (c == NULL)
    {
        c = redisAsyncConnect("127.0.0.1", 6379);
    }
    if (c->err) {
        printf("error: %s\n", c->errstr);
        return 0;

    }

    redisLibeventAttach(c, base);
    redisAsyncCommand(c, onMessage, NULL, "SUBSCRIBE CHANNEL1");

    
    //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数
    int ret = 0;
     ret = pthread_create(&tids, NULL, test_sub, NULL);
    //event_base_loopexit(base, 10);
    //test_sub(0);

    if(ret != 0)
    {
      printf( "pthread_create error: error_code=%d \n" ,ret);
      return false;
    }
    handle = tids;
    return true;
}
bool ThreadClose(uint64_t &handle)
{
    if (base != NULL)
    {
        //event_base_loopexit(base,NULL);//无法运行loopbatch后的代码
        eventFlag = false;
        int ret = -1;
        
        ret=event_base_loopexit(base,NULL);
        printf("event_base_loopexit %d\n",ret);
        
        //redisAsyncDisconnect(c);
        //redisAsyncFree(c);
        //c = NULL;

       
        ret = -1;
        while (ret != 0)
        {
            ret = event_base_loopbreak(base);
            printf("event_base_loopbreak %d\n", ret);
            usleep(1000 * 1000);
        }
        printf("event_base_loopbreak %d\n", ret);
        event_base_free(base);    
       
        base = NULL;
    }
    return true;
}
 
int main(int argc, char **argv) {
    signal(SIGPIPE, SIG_IGN);
    
    uint64_t handle;
    ThreadRun(handle);
    printf("handle %lld\n",handle);
    int count = 0;

    while (true)
    {
        usleep(1000*1000*1);//1000 0000 =1s
        printf("%d\n",count++);

        if ((count %100)==10)
        {
            printf("close thread %d\n", count++);
            ThreadClose(handle);
             
        }

        if ((count % 100) == 30)
        {
            printf("start thread %d\n", count++);
            ThreadRun(handle);

        }
    }
    return 0;
}
 
发布了45 篇原创文章 · 获赞 1 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/oSiJieMo/article/details/102602336