zoukankan      html  css  js  c++  java
  • c/c++(hiredis)异步调用redis【转】

        同步方式

    不过大多数情况下,我们采用的都是同步的调用方式。

    没错,同步的方式就是这么简单易用。

        异步方式

    不过说到了同步,那必然得说异步。同步简单,异步性能高。为了性能,或者说为了装B,必须得用一下异步调用方式才能显示得出高大上。

    当然,本文不是描述基于libevent,或者基于redis本身得ae网络库的异步方式。而是基于公司(或者自己)已有的异步服务器框架上,我们需要:

    1. 将发送redis的请求按照redis的既有协议打包到一个buffer。
    2. 将这个buffer丢给异步服务器框架,由框架负责和redis服务器建立(维护)连接,发送请求buffer,并取得redis返回的数据buffer。框架保证这个过程是异步高性能的。
    3. 然后框架会给出redis的回包buffer。我们需要按照redis的既有协议解开这个包,并得到结果。

    redis的既有协议,这里先不展开描述。回到上面的需求,我们怎么才能打包redis的请求,解包redis的返回数据呢?用习惯了同步的方式,还曾经抱怨hiredis为什么不提供一个打包的函数和一个解包的函数呢。原来是自己眼拙,没看出hiredis库的打包和解包的使用方式。

    打包函数系列:

    解包是通过一个redisReader来完成的。

    呵呵,打包和解包看来不是一个简单的函数搞定的,就原谅自己的眼拙了。哈哈。

        实战演习

    来一个简单的例子(demo.c),假设实例里面的函数

    int asyncFrameWork(const uint8_t* sendBuf, int sendBufLen, uint8_t* recvBuf, int* recvBufLen);

    就是公司高大上的异步服务器框架了啊。(汗颜一下。。。)

    或者把这个asyncFrameWork替换为目前很前沿的微线程(协程)技术,那性能也是相当高的。

    编译

    执行

    用valgrind执行一下,看结果是否正确的同时,也顺便看看是否有内存泄露。

    [amcool@leoox redisDemo]$ valgrind –leak-check=full –tool=memcheck ./demo
    ==3868== Memcheck, a memory error detector.
    ==3868== Copyright (C) 2002-2006, and GNU GPL’d, by Julian Seward et al.
    ==3868== Using LibVEX rev 1658, a library for dynamic binary translation.
    ==3868== Copyright (C) 2004-2006, and GNU GPL’d, by OpenWorks LLP.
    ==3868== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
    ==3868== Copyright (C) 2000-2006, and GNU GPL’d, by Julian Seward et al.
    ==3868== For more details, rerun with: -v
    ==3868==
    redisFormatCommand result: len = 37, cmdBuf = *3
    $3
    SET
    $7
    company
    $5
    leoox

    asyncFrameWork recv len = 5
    asyncFrameWork return : recvBuf = +OK
    , recvBufLen = 5
    redisReader get reply : 5
    r->type = 5
    ————————————-
    set key(company) OK
    ————————————-
    redisFormatCommand result: len = 28, cmdBuf = *2
    $3
    GET
    $9
    company..

    asyncFrameWork recv len = 5
    asyncFrameWork return : recvBuf = $-1
    , recvBufLen = 5
    redisReader get reply : 4
    r->type = 4
    ————————————-
    key(company..) not exists!
    ————————————-
    redisFormatCommand result: len = 26, cmdBuf = *2
    $3
    GET
    $7
    company

    asyncFrameWork recv len = 11
    asyncFrameWork return : recvBuf = $5
    leoox
    , recvBufLen = 11
    redisReader get reply : 1
    r->type = 1
    r->len = 5
    r->str = leoox
    ————————————-
    key(company), value=(leoox)
    ————————————-
    ==3868==
    ==3868== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
    ==3868== malloc/free: in use at exit: 0 bytes in 0 blocks.
    ==3868== malloc/free: 41 allocs, 41 frees, 2,352 bytes allocated.
    ==3868== For counts of detected errors, rerun with: -v
    ==3868== All heap blocks were freed — no leaks are possible.

    结果正确,并且没有内存泄露。perfect!哦,圣诞过完了,那提前说元旦快乐,新的一年要任性!

  • 相关阅读:
    Android-调用优酷SDK上传视频
    新浪微博客户端(16)-获得并显示用户昵称
    新浪微博客户端(15)-保存用户名和密码
    转:Java NIO系列教程(九) Pipe
    新浪微博客户端(14)-截取回调地址中的授权成功的请求标记,换取access_token
    iOS-AFN "Request failed: unacceptable content-type: text/plain"
    新浪微博客户端(13)-使用UIWebView加载OAuth授权界面
    iOS-(kCFStreamErrorDomainSSL, -9802)
    转:Java NIO系列教程(八) DatagramChannel
    转:Java NIO系列教程(七) Socket Channel
  • 原文地址:https://www.cnblogs.com/sunsky303/p/8117181.html
Copyright © 2011-2022 走看看