time_wheel

time_wheel实际就是个时间轮定时器,时间轮定时器就不多解释了看下高性能服务编程那本书的时间轮定时器就ok了,muduo的时间轮只不过是时间轮定时器的可以说一部分吧,
这里的一开始初始化定时器的一轮tick的次数,因为主要就是针对每一个用户都是在相同的一定时间内没有再次访问的服务端需要断开与客户端连接,因此添加客户端连接信息的时候不必要添加定时时间,只需要当前tick的时的添加的,当轮到下一轮这个相同的位置就可以断开客户端(下面再介绍中途有请求的情况)
EchoServer::EchoServer(EventLoop* loop,
                       const InetAddress& listenAddr,
                       int idleSeconds)
  : server_(loop, listenAddr, "EchoServer"),
    connectionBuckets_(idleSeconds)
{
  connectionBuckets_.resize(idleSeconds);//设置时间轮的大小
}

typedef boost::shared_ptr EntryPtr;
typedef boost::weak_ptr WeakEntryPtr;
typedef boost::unordered_set Bucket;
typedef boost::circular_buffer WeakConnectionList;

muduo::net::TcpServer server_;
WeakConnectionList connectionBuckets_;

muduo没有自己去实现时间轮这个容器,而是使用boost库中的circular_buffer,这个用法我就不介绍了,随便找个链接吧http://www.cnblogs.com/TianFang/archive/2013/02/05/2892503.html
知道原理的话自己实现这个也是没啥问题的了

muduo的断开客户端判断是根据引用计数器到0自动断开,比如客户端第一次请求就是把引用计数器自增,而收到客户端的数据的时候就会把添加tick到的circular_buffer,这样引用计数器会加1,要是当以前的添加的位置,过一轮又回到那个位置,他的引用计数器就会减一下面就贴连接请求和接收收据的代码吧

```
void EchoServer::onConnection(const TcpConnectionPtr& conn)
{
  LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> "
           << conn->localAddress().toIpPort() << " is "
           << (conn->connected() ? "UP" : "DOWN");

  if (conn->connected())
  {
    EntryPtr entry(new Entry(conn));
    connectionBuckets_.back().insert(entry);
    dumpConnectionBuckets();
    WeakEntryPtr weakEntry(entry);
    conn->setContext(weakEntry);
  }
  else
  {
    assert(!conn->getContext().empty());
    WeakEntryPtr weakEntry(boost::any_cast<WeakEntryPtr>(conn->getContext()));
    LOG_DEBUG << "Entry use_count = " << weakEntry.use_count();
  }
}
void EchoServer::onMessage(const TcpConnectionPtr& conn,
                           Buffer* buf,
                           Timestamp time)
{
  string msg(buf->retrieveAllAsString());
  LOG_INFO << conn->name() << " echo " << msg.size()
           << " bytes at " << time.toString();
  conn->send(msg);

  assert(!conn->getContext().empty());
  WeakEntryPtr weakEntry(boost::any_cast<WeakEntryPtr>(conn->getContext()));
  EntryPtr entry(weakEntry.lock());
  if (entry)
  {
    connectionBuckets_.back().insert(entry);

  }
}

在收到信息的时候需要把弱引用升级为强引用(就是muduo前面线程安全提到的棉线变铁丝)然后添加到容器中

import numpy as np import math import matplotlib.pyplot as plt import tkinter as tk import tkinter.messagebox import pandas as pd from openpyxl import load_workbook from warnings import simplefilter engine_torque = 10 i0 = 2.088 i1 = 2.928 ig = 2.929 efficiency = 0.96 Wheel_radius = 0.3059 slope = 0 #坡度单位弧度 slope_cos = math.cos(slope) slope_sin = math.sin(slope) rolling_resistance_coefficient = 0.01 air_coefficient = 0.28 face_area = 0.4 air_density = 1.2258 vehicle_speed = 0 weight = 268 step_size = 0.01 flag = 0 time = 0 vehicle_speed_plot = [] time_plot = [] def drive_force(engine_torque,i0,i1,ig,efficiency,Wheel_radius): drive_force = engine_torque*i0*ig*i1*efficiency/Wheel_radius return drive_force def rolling_resistance(weight,rolling_resistance_coefficient,slope_cos): rolling_resistance = weight*rolling_resistance_coefficient*slope_cos return rolling_resistance def air_resistance(air_coefficient,face_area,air_density,relative_speed): air_resistance = 0.5*air_coefficient*face_area*air_density*relative_speed*relative_speed return air_resistance def grade_resistance(weight,slope_sin): grade_resistance = weight*slope_sin return grade_resistance while flag==0: relative_speed = vehicle_speed vehicle_acclerate = (drive_force(engine_torque,i0,i1,ig,efficiency,Wheel_radius)-rolling_resistance(weight,rolling_resistance_coefficient,slope_cos)-air_resistance(air_coefficient,face_area,air_density,relative_speed))/weight vehicle_speed = vehicle_acclerate*step_size+vehicle_speed running_distance = relative_speed*step_size+0.5*vehicle_acclerate*step_size*step_size time = time+step_size if time == 10: flag = 1 vehicle_speed_plot.append(vehicle_speed) time_plot.append(time)
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值