通向码农的道路(enet开源翻译计划 二)


QQ 324186207群 enet交流技术,主要是为了研究tcp内部执行机制。欢迎大家增加探讨。小弟水平有限,翻译难免有误。


http://enet.bespin.org  解析enet 双向链表(无placement new) enet本身就已经局限了4095 在线人数   假设有10000人同一时候在线。enet使用list来维护每次收发,不断的销毁,释放内存,性能实在太低。

enent写的根本不严谨,无论什么结构都存储双向链表,收一个包,我也须要去遍历,究竟获取某peer。 

enet_host_service  每次事件抛出机制,实在太粗糙。说明enet  很多其它偏向就是一个学习项目,假设大量数据传输,高并发,高负载,无法满足需求顺便提下。为何server好多地方不使用stl  

问题一:不能确定STL怎样管理内存。如果就依照STL默认的方法来管理内容。则server在长时间的分配和释放内存后,easy导致内存碎片。对server的稳定有影响。然而,如果没有阅读过STL的源代码。谁又能确切地得知STL是怎样管理内存的呢?尽管可以在STL中使用自己的分配器,又可以确认STL的某些部分不会在分配器之外进行内存分配呢?

    当然,内存管理问题不是STL带来的问题,不论什么server程序本身都要考虑这个问题。原因在极少有人去阅读STL的源代码。去了解STL的内部实现机理。由于不了解,所以怀疑。由于怀疑,所以不轻易使用。

    问题二:不能确定STL在海量数据下的表现。

server一般都是海量的内存,为了提高性能大量数据保存在内存中。

在很大的规模的数据下。STL一定可以满足稳定性和效率的需求吗?

    问题三:不能确定STL在多线程环境下的表现。

以上的内存和规模的问题能够通过加深对STL的了解和測试来解决,可是多线程下的并发问题就不是那么easy攻克了。

STL不是线程安全的。在多线程环境下。对STL容器的操作都要加锁来确保正确。然后。部分高性能的场合,须要对“读-读”条件下并发进行优化,以及某些锁无关的特殊条件能够不加锁,甚至是採用流行的RCU机制…………在这个倡导多核和并发的时代,STL显得有些落后了。

传统的双向链表 普通情况我们套上 T *data 

/*双链表结构*/ 
template<class T> typedef struct node  {      T  *data;      struct node *prior;      struct node *next;    }DNode;

下面enet双向链表结构,发现结构体内无T *data ,奇怪吧?那么我们数据存储到哪里?
#list.h
typedef struct _ENetListNode{    struct _ENetListNode * next;      struct _ENetListNode * previous;  } ENetListNode;
typedef ENetListNode * ENetListIterator;
typedef struct _ENetList{    ENetListNode sentinel;  //标记当前处于某个节点位置} ENetList;

extern void enet_list_clear( ENetList * ); 
extern ENetListIterator enet_list_insert( ENetListIterator , void * ); extern void * enet_list_remove( ENetListIterator ); extern ENetListIterator enet_list_move( ENetListIterator, void *, void * );
extern size_t enet_list_size( ENetList * ); 
#define enet_list_begin(list) ((list) -> sentinel.next)  #define enet_list_end(list) (& (list) -> sentinel) 
#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
#define enet_list_next(iterator) ((iterator) -> next)#define enet_list_previous(iterator) ((iterator) -> previous)
#define enet_list_front(list) ((void *) (list) -> sentinel.next) #define enet_list_back(list) ((void *) (list) -> sentinel.previous)
#main.cpp
#define ENET_CALLBACK __cdecltypedef struct _ENetCallbacks{    void * ( ENET_CALLBACK * malloc ) ( size_t size );    void ( ENET_CALLBACK * free ) ( void * memory );    void ( ENET_CALLBACK * no_memory ) ( void );} ENetCallbacks;
static ENetCallbacks callbacks = { malloc, free, abort };
void * enet_malloc( size_t size ){    void * memory = callbacks.malloc( size );        if( memory == NULL )        callbacks.no_memory();        return memory;}void  enet_free( void * memory ){    callbacks.free( memory );}
 struct ENetOutgoingCommand{    ENetListNode list;    int a;};
int main()
ENetOutgoingCommand *enet_outgoing;
ENetList enet_test;
enet_list_clear(&enet_test); //重置双向链表,将头指针和尾指针指向第一个空节点enet_outgoing = (ENetOutgoingCommand *)enet_malloc( sizeof( ENetOutgoingCommand ) );enet_outgoint->a = 100;enet_list_insert( enet_list_end( &enet_test ), enet_outgoing ); //malloc 数据插入到双向链表的尾部ENetListIterator currentCommand;currentCommand = enet_list_begin(&enet_test ); //这里取出双向链表头节点
while( currentCommand != enet_list_end( &enet_test ) ) //遍历链表{    ENetOutgoingCommand * t1 = (ENetOutgoingCommand *)currentCommand;  //通过强转来获取数据    cout << t1->a << endl;    currentCommand = enet_list_next( currentCommand ); //获取下个节点    enet_list_remove( &t1->list ); //删除当前节点    enet_free( t1 );//删除内存,避免内存泄漏  while( Exit ){    開始server循环机制,这个循环设计非常的糟糕,每次一但server触发事件,会调用不同类型事件。

    解决的方法,每个while 我用队列收一把全部数据。然后在逐个遍历,这样添加了非常小延迟,可是提高了吞吐量。    每次收到数据后。又从新  enet_protocol_send_outgoing_commands 開始检查第一个玩家,应该做个全局变量,存储当前遍历       位置
    ENetEvent event;    if( enet_host_service( server, &event, 1 ) )    {        switch( event.type )        {        case ENET_EVENT_TYPE_CONNECT:        {            Conneted( event.peer->connectID, event.peer->address.host, event.peer->address.port );            peersConn.Insert( event.peer->connectID, event.peer );            break;        }        case ENET_EVENT_TYPE_RECEIVE:        {            //bIdle = false;            //Recived( event.peer->connectID, event.packet->data, event.packet->dataLength );            break;        }        case ENET_EVENT_TYPE_DISCONNECT:        {            cout << "close client_fd" << endl;            //Disconneted( event.connectID );            break;        }
        case ENET_EVENT_TYPE_PING:        {            cout << "enter reconnect:" << time( 0 ) << endl;            //ReConnection(event.peer->connectID);            break;        }        }
    }
}

/** Waits for events on the host specified and shuttles packets between    the host and its peers.
    @param host    host to service    @param event   an event structure where event details will be placed if one occurs                   if event == NULL then no events will be delivered   

转载于:https://www.cnblogs.com/lytwajue/p/7345050.html

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值