C++11 读写支持百万并发cache处理模型 不知道算不算。

来源:互联网 发布:php截取html字符串 编辑:程序博客网 时间:2024/05/17 17:14

实现了个,读取写入两百万的模型,还是有点问题。

直接上代码,问题在下面。

#include <iostream>
#include <mutex>
#include <chrono>
#include <condition_variable>
class MyCache {
public:
    MyCache(int sum);
    ~MyCache();
    int read(char* p, int len);
    int write(const char* p, int len);
private:
    char* m_pBuf;
    char* m_pBufEnd;
    char* m_pRead;
    char* m_pWrite;
    int m_nSum;
    int m_nUsed;
    int m_nLast;
    std::mutex m_mutex;
};

MyCache::MyCache(int sum)
{
    m_pBuf = new char[sum];
    m_pRead = m_pBuf;
    m_pWrite = m_pBuf;
    m_pBufEnd = m_pBuf + sum;
    m_nSum = sum;
    m_nUsed = 0;
    m_nLast = sum;
}
MyCache::~MyCache() {
    if (m_pBuf != NULL) {
        delete[] m_pBuf;
        m_pBuf = NULL;
    }
}

int MyCache::read(char* p, int len)
{
    int nRet = len;

    m_mutex.lock();
    if (m_nUsed < len)
    {
        m_mutex.unlock();
        return 0;
    }

    if (m_pBufEnd - m_pRead >= len)
    {
        memcpy(p, m_pRead, len);
        m_pRead += len;
        m_nUsed -= len;
        m_nLast += len;
    }
    else
    {
        memcpy(p, m_pRead, m_pBufEnd - m_pRead);
        memcpy(p + (m_pBufEnd - m_pRead), m_pBuf, len - (m_pBufEnd - m_pRead));
        m_pRead = m_pBuf + len - (m_pBufEnd - m_pRead);
        m_nUsed -= len;
        m_nLast += len;
    }
    m_mutex.unlock();

    return nRet;
}
int MyCache::write(const char* p, int len)
{
    int nRet = len;
    m_mutex.lock();

    if (m_nLast < len)
    {
        m_mutex.unlock();
        return 0;
    }

    if (m_pBufEnd -m_pWrite >= len)
    {
        memcpy(m_pWrite, p, len);
        m_pWrite += len;
        m_nUsed += len;
        m_nLast -= len;
    }
    else
    {
        memcpy(m_pWrite, p, m_pBufEnd - m_pWrite);
        memcpy(m_pBuf, p+ (m_pBufEnd - m_pWrite), len- (m_pBufEnd - m_pWrite));
        m_pWrite = m_pBuf + len - (m_pBufEnd - m_pWrite);
        m_nUsed += len;
        m_nLast -= len;
    }

    m_mutex.unlock();
    return nRet;
}

MyCache gm(102400);
bool gRun = true;
bool gW = false;
bool gR = false;
std::mutex gWmx, gRmx;
std::string gstr = "123456789";
std::condition_variable gRcv, gWcv;
void threadRead()
{
    char str[20] = { 0 };
    int nRet = 0;
    int OK = 0;
    int Err = 0;
    while (gRun) {
        memset(str, 0, 20);
        nRet = gm.read(str, 9);
        if (nRet>0)
        {
            OK++;
            //std::unique_lock<std::mutex> lock(gRmx);
            //gR = true;
            //gRcv.notify_one();
        }
        else
        {
            //{
            //    std::unique_lock<std::mutex> lock(gWmx);
            //    while (!gW && gRun) {
            //        gWcv.wait(lock);
            //    }
            //    gW = false;
            //}
            
            Err++;
            std::this_thread::sleep_for(std::chrono::nanoseconds(1000));
        }
    }
    printf("R_OK/ERR:%d/%d\n", OK, Err);
    //std::cout << "R-OK/ERR:" << OK << "/" << Err << std::endl << fflush;
}
void threadWrite()
{
    int nRet = 0;
    int OK = 0;
    int Err = 0;
    while (gRun) {
        nRet = gm.write(gstr.c_str(), 9);
        if (nRet>0)
        {
            OK++;
            //std::unique_lock<std::mutex> lock(gWmx);
            //gW = true;
            //gWcv.notify_one();
        }
        else
        {
            //{
            //    std::unique_lock<std::mutex> lock(gRmx);
            //    while (!gR && gRun) {
            //        gRcv.wait(lock);
            //    }
            //    gR = false;
            //}
            
            Err++;
            //std::this_thread::sleep_for(std::chrono::nanoseconds(1));
        }
    }
    printf("W_OK/ERR:%d/%d\n", OK, Err);
    //std::cout << "W-OK/ERR:" << OK << "/" << Err << std::endl << fflush;
}

//std::int64_t n = 10000000;
//std::int64_t testInt() {
//
//    int i = 0;
//    std::chrono::time_point<std::chrono::system_clock> t = std::chrono::system_clock::now();
//    while (i++ < n) {
//        int n=i;
//        int n1 = i;
//        int n2 = i;
//        int n3 = i;
//    }
//    return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count();
//}
//std::int64_t testPlus() {
//    int i = 0;
//    int n = 0;
//    std::chrono::time_point<std::chrono::system_clock> t = std::chrono::system_clock::now();
//    while (i++ < n) {
//        n = i-10110;
//        n = i - 10110;
//        n = i - 10011;
//        n = i - 10110;
//    }
//    return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - t).count();
//}



int main()
{
    
    //std::cout << "Int:" << testInt() << std::endl;
    //std::cout << "Plus:" << testPlus() << std::endl;
    std::thread tR(threadRead);
    std::thread tR1(threadRead);
    std::thread tW(threadWrite);

    std::this_thread::sleep_for(std::chrono::seconds(10));

    gRun = false;
    
    if (tR.joinable())
    {
        tR.join();
    }
    if (tR1.joinable())
    {
        tR1.join();
    }
    if (tW.joinable())
    {
        tW.join();
    }


    getchar();
    return 0;
}

运行10秒

输出结果为:

W_OK/ERR:20998482/11599
R_OK/ERR:10461488/3398
R_OK/ERR:10535596/3429

写入两千多万,读取 也是两千多万,没有清空cache。每秒两百万吧。

I76700CPU,用了三个线程,CPU百分之三十多点有点浮动。

只是数据有点少。


如果不sleep,用conditional(注释部分打开,关闭 线程sleep) 输出结果却只有一千万,每秒一百万,

R_OK/ERR:5443235/98386
W_OK/ERR:10811982/0
R_OK/ERR:5368683/94922

CPU比上一次还高点,稳定在百分之三十八。

不知道怎么回事。

0 0
原创粉丝点击