首页 > 其他分享 >UMF高并发

UMF高并发

时间:2022-11-13 09:11:24浏览次数:29  
标签:UMF ip 并发 UINT16 VOS UINT32 ipToTableIndex PortMapHashtable

cmake_minimum_required(VERSION 3.0.0)
project(hash VERSION 0.1.0)
MESSAGE(${PROJECT_SOURCE_DIR})
SET(
    APP_SRC
    ${PROJECT_SOURCE_DIR}/main.cpp
    ${PROJECT_SOURCE_DIR}/PortMapHashtable.cpp
)
add_executable(${PROJECT_NAME} ${APP_SRC})
add_compile_options(-Wall)
target_link_libraries(${PROJECT_NAME} pthread)
#include <iostream>
#include <windows.h>
#include "PortMapHashtable.h"

using std::cout;
PortMapHashtable test;
int port = 50,ip = 100;
void TEST_1() {
    test.InsertPort(1,123,456);
    test.InsertPort(1,123,789);
    test.InsertPort(10,123,456);
    test.InsertPort(12,12,12);

    cout << test.GetBindPort(1,123) << "\n";
    cout << test.GetBindPort(456,456) << "\n";
    cout << test.GetBindPort(10,123) << "\n";
    cout << test.GetBindPort(12,12) << "\n";
}
void* readFunc(void*);
void* writeFunc(void*);
void TEST_2() {
    pthread_t readThread[2];
    pthread_t writeThread[2];

    pthread_create(readThread + 0, nullptr, readFunc, nullptr);

    pthread_create(writeThread + 0, nullptr, writeFunc, nullptr);
    
    pthread_create(readThread + 1, nullptr, readFunc, nullptr);

    pthread_create(writeThread + 1, nullptr, writeFunc, nullptr);


    for (int i = 0;i < 2;++i) {
        pthread_join(readThread[i], nullptr);
        pthread_join(writeThread[i], nullptr);
    }
  
}
int main() {


    if (test.Init()) {
        // TEST_1();
        TEST_2();
    }
    else {
        cout << "初始化失败!\n";
    }

    return 0;
}

void* writeFunc(void*) {
    while (1) {
        ++port;
        test.InsertPort(ip,100,port);
        // printf("w data:%6d, tid:%6d\n", port, pthread_self());
    }
}

void* readFunc(void*) {
    while (1) {
        int result = test.GetBindPort(ip,100);
        // printf("r data:%6d, tid:%6d\n",result, pthread_self());
    }
}
#include "PortMapHashtable.h"
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdlib.h>
#include <pthread.h>
#include <windows.h>
using std::cout;
using std::endl;

HashTableIndexNode::HashTableIndexNode(VOS_UINT32 key,VOS_UINT16* value) 
    : key(key),value(value)
        {}
bool HashTableIndexNode::operator < (const HashTableIndexNode rhs) const {
        return key < rhs.key;
}
static VOS_VOID ErrorLog(const char * const errLog) {
    printf("%s\n",errLog);
} 
PortMapHashtable::PortMapHashtable()
    :m_numOfIp(0) 
        {}
PortMapHashtable::~PortMapHashtable() {
    pthread_rwlock_destroy(&rwlock);
}
VOS_BOOL PortMapHashtable::Init() {
    for (auto i = 0;i < m_numOfIp;++i) {
        if (m_ipToTableIndex[i].value != nullptr) {
            free(m_ipToTableIndex[i].value);
            m_ipToTableIndex[i].value = nullptr;
        }
    }
    m_numOfIp = 0;
    auto lockInitResult = pthread_rwlock_init(&rwlock,nullptr);
    if (lockInitResult == 0) {
        return VOS_TRUE;
    }
    else {
        ErrorLog("ReadWriteLock init fail");
        return VOS_FALSE;
    }
}
VOS_BOOL PortMapHashtable::InsertPort(VOS_UINT32 ip,VOS_UINT16 portIn,VOS_UINT16 portOut) {
    using std::swap;

    auto hashTablePtr = GetHashTablePtr(ip);

    if (hashTablePtr == nullptr) {
        if (m_numOfIp == MAXIMUM_NUMBER_OF_MACHINE) {
            ErrorLog("Too much machine");
            return VOS_FALSE;
        }
        else {
            // 加读写锁
            auto initHashTablePtr = InitHashTable();
            if (initHashTablePtr == nullptr) {
                ErrorLog("initHashTablePtr == nullptr");
                return VOS_FALSE;
            }
            else {
                AddHashTable(ip,portIn,portOut,initHashTablePtr);
                return VOS_TRUE;
            }
        }
    }
    else {
        hashTablePtr[portIn] = portOut;
        return VOS_TRUE;
    }
}
VOS_VOID PortMapHashtable::AddHashTable(VOS_UINT32 ip,VOS_UINT16 portIn,VOS_UINT16 portOut,VOS_UINT16* initHashTablePtr) {
    using std::swap;
    pthread_rwlock_wrlock(&rwlock);
    Sleep(1000);
    printf("w data:%6d, tid:%6d\n", portOut, pthread_self());
    m_ipToTableIndex[m_numOfIp] = HashTableIndexNode(ip,initHashTablePtr); 
    initHashTablePtr[portIn] = portOut;
    for (VOS_UINT32 i = m_numOfIp; i > 0; --i) {
        if (m_ipToTableIndex[i - 1].key > m_ipToTableIndex[i].key) {
            swap(m_ipToTableIndex[i - 1].key,m_ipToTableIndex[i].key);
            swap(m_ipToTableIndex[i - 1].value,m_ipToTableIndex[i].value);
        }
        else {
            break;
        }
    }
    ++m_numOfIp;
    
    pthread_rwlock_unlock(&rwlock);
}
VOS_UINT16* PortMapHashtable::GetHashTablePtr(VOS_UINT32 ip) {
    using std::make_pair;
    pthread_rwlock_rdlock(&rwlock);
    Sleep(1000);
    auto lowPtr = std::lower_bound(m_ipToTableIndex,m_ipToTableIndex + m_numOfIp,HashTableIndexNode(ip,nullptr));
    auto uppPtr = std::upper_bound(m_ipToTableIndex,m_ipToTableIndex + m_numOfIp,HashTableIndexNode(ip,nullptr));
    VOS_UINT16* result = nullptr;
    if (lowPtr != uppPtr) {
        result = lowPtr -> value;
    }
    pthread_rwlock_unlock(&rwlock);
    return result;
}

VOS_UINT16 PortMapHashtable::GetBindPort(VOS_UINT32 ip,VOS_UINT16 portIn) {
    auto hashTablePtr = GetHashTablePtr(ip);
    if (hashTablePtr == nullptr) {
        ErrorLog("invalid ip");
        return 0;
    }
    else {
        return hashTablePtr[portIn];
    }
}
VOS_UINT16* PortMapHashtable::InitHashTable() {
    constexpr VOS_UINT32 hashTableSize = (1 << 16); 
    auto ptr = (VOS_UINT16*)malloc(hashTableSize * sizeof(VOS_UINT16));
    if (ptr == nullptr) {
        ErrorLog("malloc() == nullptr");
        return ptr;
    }
    else {
        memset(ptr ,0 ,hashTableSize * sizeof(VOS_UINT16));
        return ptr;
    }
}
#include <cstdint>
#include <map>
#include <pthread.h>

using VOS_VOID = void;
using VOS_UINT16 = std::uint16_t;
using VOS_UINT32 = std::uint32_t;
using VOS_BOOL = int;
constexpr VOS_BOOL VOS_TRUE = 1;
constexpr VOS_BOOL VOS_FALSE = 0;

struct HashTableIndexNode {
    HashTableIndexNode() = default;
    HashTableIndexNode(VOS_UINT32 key,VOS_UINT16* value);
    VOS_UINT32 key;
    VOS_UINT16* value;
    bool operator < (const HashTableIndexNode rhs) const;
};

class PortMapHashtable {
    public :
        static constexpr VOS_UINT32 MAXIMUM_NUMBER_OF_MACHINE = 1000;
    public :
        PortMapHashtable();
        ~PortMapHashtable();
        VOS_BOOL Init();
        VOS_BOOL InsertPort(VOS_UINT32 ip,VOS_UINT16 portIn,VOS_UINT16 portOut);
        VOS_UINT16 GetBindPort(VOS_UINT32 ip,VOS_UINT16 portIn);
    private :
        VOS_VOID AddHashTable(VOS_UINT32 ip,VOS_UINT16 portIn,VOS_UINT16 portOut,VOS_UINT16* initHashTablePtr);
        VOS_UINT16* GetHashTablePtr(VOS_UINT32 ip);
        VOS_UINT16* InitHashTable();
    private :
        pthread_rwlock_t rwlock;
        HashTableIndexNode m_ipToTableIndex[MAXIMUM_NUMBER_OF_MACHINE];
        VOS_UINT32 m_numOfIp;
};

标签:UMF,ip,并发,UINT16,VOS,UINT32,ipToTableIndex,PortMapHashtable
From: https://www.cnblogs.com/XDU-mzb/p/16885398.html

相关文章

  • Java消费者生产者模式,并发控制。
    概论举个例子:有一个固定容量的货架,生产者放商品进来,消费者拿商品出去,为了保证正常放入和正常拿出(数据的正确性,不会出现超过容量的存放,拿到空气)。使用同步块中的wait和n......
  • JUC并发编程
    学习文档:https://blog.csdn.net/weixin_44491927/article/details/108560692学习视频:https://www.bilibili.com/video/BV1B7411L7tE/ ......
  • Kafka RecordAccumulator 三 高并发写入数据
    KafkaRecordAccumulator三高并发写入数据首先我们客户端会通过多线程的方式来发送消息(一般业务需求可能会通过业务系统或者大数据流计算系统如SparkStreaming或者Fl......
  • scratch程序设计-并发篇
    scratch程序设计篇 随着孩子们逐渐入门scratch,开始自己拼搭程序建立项目,他们对角色实现动作效果的要求也更高,这时候开始遇到了“并行程序”这个问题。我之前讲过,6-8岁这......
  • 统计开始目录及其子目录下的指定类型文件中的单词(使用多线程、并发多线程(mappedReduce
    #include<QList>#include<QMap>#include<QTextStream>#include<QString>#include<QStringList>#include<QDir>#include<QElapsedTimer>#include<QApplicati......
  • nginx高并发优化之静态文件缓存配置
    一、配置http{open_file_cachemax=65535inactive=20s;open_file_cache_valid30s;open_file_cache_min_uses4;open_file_cache_errorson;}二、说明NGINX虽然已......
  • 《Go 语言并发之道》读书笔记(一)
    已经把《Go语言并发之道》通读了一遍,非常不错的一本书,对于理解掌握Go语言的并发知识有很大的帮助,接下来我会把书中有用的知识通过代码示例出来,把一些比较好的知识点记录下......
  • Java并发编程——基础知识(一)
    1.进程与线程1.1基本概念进程:对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发线程:进程的子任务,是CPU调度和分派的基本单位,用于保证程序......
  • 性能测试-并发、在线、TPS之前的关系、以及容量场景规划
    实战出真知举例,日常操作步骤,1、打开首页 2、登录  3、点击品类4、选择商品5、点击购买6、订单详情7、支付成功8、退出  ,总请求数假设为100 1、单个在......
  • 高并发下的幂等性保证
    1幂等性1.1定义幂等概念来自数学,表示对数据源做N次变换和1次变换的结果是相同的。在工程中幂等性用来表示用户对于同一操作发起的一次请求或者多次请求的结果是一致的,......