与libev和pthread的异步hiredis,我做错了什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了与libev和pthread的异步hiredis,我做错了什么?相关的知识,希望对你有一定的参考价值。

我正在为一个小的单色显示器编写GUI,我想每秒更新屏幕上的数据。

数据存储在redis数据库中,我试图使用pthread,libev和异步hiredis调用进行协调。

我的计划是让一个线程每秒从数据库中提取新数据并存储本地副本以便快速访问。

更新屏幕的另一个线程将随意访问该数据,而无需等待数据库访问。

第一个问题,我的方法是否正确?

第二个问题,为什么我每秒都无法轮询数据库?我想我可以切换到同步方法并让它工作,但这是正确的方法吗?

这是相关代码:

int main(int argc, char *argv[])
{
  pthread_t dataThread;
  pthread_t guiThread;

  pthread_create(&dataThread, NULL,  dataHandler, NULL);
  pthread_create(&guiThread, NULL, guiHandler, NULL);

  while (true)
  {
    sleep(10);
  }

  return 0;
}

在下面,如果我在redisAsync命令之后在while循环中移动ev_loop(EV_DEFAULT_ 0);,我的回调将被调用第一个循环,但永远不会再次。它的方式,我的回调永远不会被调用。

void* dataHandler(void *ptr)
{ 
  m_ctx = redisAsyncConnect("127.0.0.1", 6379); 
  if (m_ctx->err) {

    printf("Redis async connection failed. Error: %s
", m_ctx->errstr);
    exit(-1);
  }

  redisLibevAttach(EV_DEFAULT_ m_ctx);
  redisAsyncSetConnectCallback(m_ctx,connectCallback);
  redisAsyncSetDisconnectCallback(m_ctx,disconnectCallback);
  ev_loop(EV_DEFAULT_  0);

  while (true)
  {
    int result;

    result = redisAsyncCommand(m_ctx, updateCallback, (char*)"data1", "HGET data1 data");
    printf("result: %d
", result);
    result = redisAsyncCommand(m_ctx, updateCallback, (char*)"data2", "HGET data2 data");
    printf("result: %d
", result);
    //ev_loop(EV_DEFAULT_  0); <- this will work one time
  }

  redisAsyncDisconnect(m_ctx);  
  return 0;
}

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

  printf("%s: %s
", (char*)privdata, reply->str);
}

void* guiHandler(void *ptr)
{
  while (true)
  {
    // Update the GUI accordingly
    sleep(1);
  }
}
答案

首先,我建议您在使用之前阅读libev手册:http://man7.org/linux/man-pages/man3/event.3.html

现在为您的代码,ev_loop函数将启动一个事件循环,您只需通过2个HGET操作“提供”它。为了添加更多操作,您需要为事件循环添加附加事件,但我不确定它是否适合您的情况。如果您的线程的目的只是每隔X秒获取一次数据库,为什么要使用异步方法呢? IMO只使用hiredis sync API

以上是关于与libev和pthread的异步hiredis,我做错了什么?的主要内容,如果未能解决你的问题,请参考以下文章

使用 libevent 的异步 Redis 池

Libevent:获取接受的连接列表

pthread 向 libevent 添加一个套接字但退出

解决“libevent-pthreads-2.1 cannot open shared object file“问题

libuv和libev 异步I/O库的比较

libev和libuv的区别