muduo网络库之net库源码分析(1)

详解 Muduo 网络服务和日志模块 这篇文章主要目的是介绍muduo 的网络服务模块和日志模块。 阅读详情

<TCP网络编程本质>

TCP网络编程最本质是的处理三个半事件:
连接建立:服务器accept(被动)接受连接,客户端connect(主动)发起连接
连接断开:主动断开(close、shutdown),被动断开(read返回0)
消息到达:文件描述符可读
消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件;这里的发送完毕是指数据写入操作系统缓冲区(如果数据全部填到了内核缓冲区那么调用回掉函数OnWriteComplete函数),将由TCP协议栈负责数据的发送与重传,不代表对方已经接收到数据。对于高流量的服务就要关心这个事件了,因为内核缓冲区可能不足以容纳数据,此时我们要将数据追加到应用层的发送缓冲区,如果内核缓冲区空闲了,那么就把应用层缓冲区中的数据发送出去,发送完了之后,也会调用OnWriteComplete函数。


下图演示了消息到达后和消息发送的数据处理流程:




下面我们看一下TcpSerer如何设置上面三个半事件的回调函数的:



EchoServer类是用户自己实现的类,由于muduo使用的是基于对象编程思想,所以从上面可以看出EchoServer包含TcpServer实例,而EcpServer这个类中又包含了上面set*开头的几个函数,它门分别用于注册链接建立和断开、消息到达、数据发送完毕这三个回调函数,其中setConnectionCallback同时是链接建立和断开的回调函数。所以我们如何使用EchoServer呢?很明显我们可以先定义EchoServer类型,这个类型包含我们自己实现的事件回调函数,并且包含TcpServer实例,然后调用TcpServer实例中的函数注册回调函数。

TcpServer使用实例如下:
    EchoServer.h源码如下:
class EchoServer
{
 public:
  EchoServer(muduo::net::EventLoop* loop,
             const muduo::net::InetAddress& listenAddr);

  void start();  // calls server_.start();

 private:
  void onConnection(const muduo::net::TcpConnectionPtr& conn);//链接建立或断开回调函数

  void onMessage(const muduo::net::TcpConnectionPtr& conn,   //收到消息后回调函数
                 muduo::net::Buffer* buf,
                 muduo::Timestamp time);

  muduo::net::EventLoop* loop_;  
  muduo::net::TcpServer server_; //包含注册三个半事件回调函数的方法
};

EchoServer.cpp源码如下:
#include "echo.h"

#include <muduo/base/Logging.h>

#include <boost/bind.hpp>

// using namespace muduo;
// using namespace muduo::net;

EchoServer::EchoServer(muduo::net::EventLoop* loop,
                       const muduo::net::InetAddress& listenAddr)
  : loop_(loop),
    server_(loop, listenAddr, "EchoServer")
{//注册回调函数
  server_.setConnectionCallback(
      boost::bind(&EchoServer::onConnection, this, _1));
  server_.setMessageCallback(
      boost::bind(&EchoServer::onMessage, this, _1, _2, _3));
}

void EchoServer::start()
{
  server_.start();
}

void EchoServer::onConnection(const muduo::net::TcpConnectionPtr& conn)
{
  LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> "
           << conn->localAddress().toIpPort() << " is "
           << (conn->connected() ? "UP" : "DOWN"); //<span style="font-family: Arial, Helvetica, sans-serif;">conn->connected()判断链接断开还是建立链接 </span>
}

void EchoServer::onMessage(const muduo::net::TcpConnectionPtr& conn, //只是简单回射
                           muduo::net::Buffer* buf, 
                           muduo::Timestamp time)
{
  muduo::string msg(buf->retrieveAllAsString());
  LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, "
           << "data received at " << time.toString();
  conn->send(msg);
}

main.cpp源码如下:
#include "echo.h"

#include <muduo/base/Logging.h>
#include <muduo/net/EventLoop.h>

// using namespace muduo;
// using namespace muduo::net;

int main()
{
  LOG_INFO << "pid = " << getpid();
  muduo::net::EventLoop loop;
  muduo::net::InetAddress listenAddr(2007);
  EchoServer server(&loop, listenAddr);
  server.start();
  loop.loop(); //监听事件
}


<这里首先分析什么也不做的EventLoop类,后面再深入分析>

one loop per thread意思是说每个线程最多只能有一个EventLoop对象。
EventLoop对象构造的时候,会检查当前线程是否已经创建了其他EventLoop对象,如果已创建,终止程序(LOG_FATAL)
EventLoop构造函数会记住本对象所属线程(threadId_)。
创建了EventLoop对象的线程称为IO线程,其功能是运行事件循环(EventLoop::loop)

//EventLoop.cpp的代码本身很复杂,这里是把它精简后的源码
#include <muduo/net/EventLoop.h>
#include <muduo/base/Logging.h>
#include <poll.h>

using namespace muduo;
using namespace muduo::net;

namespace
{
// 当前线程EventLoop对象指针
// __thread线程局部存储,也就是每个线程都有一个这个变量
__thread EventLoop* t_loopInThisThread = 0;
}

EventLoop* EventLoop::getEventLoopOfCurrentThread()
{
  return t_loopInThisThread;
}

EventLoop::EventLoop()
  : looping_(false),  //是否处于循环状态
    threadId_(CurrentThread::tid()) //把线程id设置为EventLoop对象所属的线程
{
  LOG_TRACE << "EventLoop created " << this << " in thread " << threadId_;
  // 如果当前线程已经创建了EventLoop对象,终止(LOG_FATAL)
  if (t_loopInThisThread)
  {
    LOG_FATAL << "Another EventLoop " << t_loopInThisThread
              << " exists in this thread " << threadId_;
  }
  else
  {
    t_loopInThisThread = this;  //设置当前线程EventLoop对象指针
  }
}

EventLoop::~EventLoop()
{
  t_loopInThisThread = NULL;
}

// 事件循环,该函数不能跨线程调用
// 只能在创建该对象的线程中调用
void EventLoop::loop()
{
  assert(!looping_);
  // 断言当前处于创建该对象的线程中
  assertInLoopThread();
  looping_ = true;
  LOG_TRACE << "EventLoop " << this << " start looping";

  ::poll(NULL, 0, 5*1000);  //什么都没做只是简单地休息5秒钟

  LOG_TRACE << "EventLoop " << this << " stop looping";
  looping_ = false;
}

void EventLoop::abortNotInLoopThread()
{
  LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this
            << " was created in threadId_ = " << threadId_
            << ", current thread id = " <<  CurrentThread::tid();
}

//EventLoop.h精简后的源码如下
#ifndef MUDUO_NET_EVENTLOOP_H
#define MUDUO_NET_EVENTLOOP_H

#include <boost/noncopyable.hpp>

#include <muduo/base/CurrentThread.h>
#include <muduo/base/Thread.h>

namespace muduo
{
namespace net
{

///
/// Reactor, at most one per thread.
///
/// This is an interface class, so don't expose too much details.
class EventLoop : boost::noncopyable
{
 public:
  EventLoop();
  ~EventLoop();  // force out-line dtor, for scoped_ptr members.

  ///
  /// Loops forever.
  ///
  /// Must be called in the same thread as creation of the object.
  ///
  void loop();
  
  //断言EventLoop是否处于创建它的线程当中
  void assertInLoopThread()
  {
    if (!isInLoopThread())
    {
      abortNotInLoopThread();
    }
  }
  
  //如果当前线程id和创建EventLoop的线程id一致那么返回true
  bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }  

  static EventLoop* getEventLoopOfCurrentThread();

 private:
  void abortNotInLoopThread();
  
  bool looping_; /* atomic */    //标志是否处于EventLoop状态
  const pid_t threadId_;		// 当前对象所属线程ID
};

}
}
#endif  // MUDUO_NET_EVENTLOOP_H


正确使用的实例:

#include <muduo/net/EventLoop.h>
#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

void threadFunc()
{
	printf("threadFunc(): pid = %d, tid = %d\n",
		getpid(), CurrentThread::tid());

	EventLoop loop;
	loop.loop();
}

int main(void)
{
	printf("main(): pid = %d, tid = %d\n",
		getpid(), CurrentThread::tid());

	EventLoop loop;

	Thread t(threadFunc);
	t.start();

	loop.loop();//只是等待5秒
	t.join();
	return 0;
}

错误的使用实例:

#include <muduo/net/EventLoop.h>
#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

EventLoop* g_loop;

void threadFunc()
{
	g_loop->loop();  //错误!!!在不是创建该EventLoop实例的线程中调用了该实例的loop函数,loop函数不能跨线程调用
}

int main(void)
{
	EventLoop loop;
	g_loop = &loop;
	Thread t(threadFunc);
	t.start();
	t.join();
	return 0;
}


Muduo网络库源码分析之Acceptor和TcpServer Acceptor 用于 accept 一个 TCP 连接,accept 接受成功后通知 TCP 连接的使用者。Acceptor 主要是供 TcpServer 使用的,其生命期由后者控制。一个 Acceptor 相当于持有服务端的一个 socket 描述符,该 socket 可以 accept 多个 TCP 客户连接,这个 accept 操作就是 Acceptor 实现的。 这里用到了一些封装好 阅读详情

相关推荐

Muduo网络库源码分析之对socket及其相关操作的封装

主要涉及到的类和实现文件有: Endian.h 提供了字节序转换的函数。 Socket.h/Socket.cc socketfd 的封装,提供了绑定地址、开始listen、接受连接等操作,并可设置套接字选项。 InetAddress.h/InetAddress.cc 套接字地址的封装,提供了多种方式初始化一个地址,还提供方法从地址中拿到 ip 和 port。 SocketsOps.h/

Tanswer_ 1483

陈硕《Linux多线程服务端编程》中的EventLoop Reactor 的 c++11 版本

把原书第8章的例子《设计Reactor——如何从头开始编写非阻塞网络库》 地址:https://github.com/chenshuo/recipes/tree/master/reactor 用 c++11 搞了一遍,并且简化到全部代码放在一个文件中,方便察看。 步骤0:什么都不做的 event loop 事件循环 EventLoop, assertInLoopThread() 这个步...

found的专栏 1075

【maxENT】从数据到地图:R语言实现最大熵物种分布建模全流程解析

本文详细解析了如何使用R语言实现最大熵模型(MaxEnt)进行物种分布建模的全流程。从数据准备、环境变量处理到模型训练与参数调优,再到模型评估与结果可视化,提供了实用的代码示例和避坑指南。特别适合生态学研究者利用最大熵模型处理物种分布数据,提升研究效率。

weixin_27244795的博客 216

muduo网络库源码复现笔记(十七):什么都不做的EventLoop

Muduo网络库简介 muduo 是一个基于 Reactor 模式的现代 C++ 网络库,作者陈硕。它采用非阻塞 IO 模型,基于事件驱动和回调,原生支持多核多线程,适合编写 Linux 服务端多线程网络应用程序。 muduo网络库的核心代码只有数千行,在网络编程技术学习的进阶阶段,muduo是一个非常值得学习的开源库。目前我也是刚刚开始学习这个网络库的源码,希望将这个学习过程记录下来。这个网络库的源码已经发布在GitHub上,可以点击这里阅读。目前Github上这份源码已经被作者用c++11重写,我学习的

梁熙民的csdn博客 489

玩转ubuntu18 --机器视觉方面(yolo算法识别及摄像头和cmake问题解决)

玩转ubuntu18 --机器视觉方面(yolo v3算法识别) 1.YOLO的简介 工作原理 先前的检测系统重新调整分类器或本地化器以执行检测。他们将模型应用于多个位置和比例尺的图像。图像的高分区域被视为检测。 我们使用完全不同的方法。我们将单个神经网络应用于整个图像。该网络将图像划分为区域,并预测每个区域的边界框和概率。这些边界框按预测概率加权。 我们的模型比基于分类器的系统具有几个优势。它在测试时间查看整个图像,因此其预测由图像中的全球上下文提供信息。它还通过单一网络评估进行预测,这与R-CNN等系统

qq_53951823的博客 1556

ESP32学习,驱动LED点阵屏,SD卡播放GIF动图

搬运就可以实现效果,如果有不足,请批评指正。下步该学一下如何文章上视频了,老是截图不方便展示效果。

u011625956的博客 1868

muduo库EventLoop类源码解析

EventLoop也称为事件循环,从调用epoll_wait系统调用捞取到就绪事件到再次阻塞到epoll_wait上(阻塞到内核中的就绪队列上了)称为一次事件循环。muduo库的EventLoop在捞取完就绪事件后会立即执行就绪事件的回调。EventLoop还有一个线程安全的任务队列。在执行完就绪事件的回调后不会立即阻塞到epoll_wait上,他会在执行完任务队列中的任务后在阻塞到就绪队列上。为什么要搞一个线程安全的任务队列呢?muduo库的设计思想是。

2301_79796701的博客 1625

液晶电视维修必看:TCON逻辑板故障排查全指南(附常见问题解决方案)

本文详细解析了液晶电视TCON逻辑板的工作原理与故障排查方法,涵盖LVDS信号处理、DC-DC电压系统等核心知识。提供从基础测量到高级维修的完整指南,帮助技术人员快速诊断黑屏、竖线等常见故障,并给出预防性维护建议,提升维修效率与成功率。

weixin_42535461的博客 616

muduo库net源码分析一(网络编程本质)

TCP网络编程最本质的是处理三个半事件 1、连接建立:服务器accept(被动)接受连接,客户端connect(主动)发起连接。 2、连接断开:主动断开(close、shutdown),被动断开(read返回0)。 3、消息到达:文件描述符可读。 4、消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件,这里的发送完毕是指数据写入操作系统缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对方已经接收到数据。对于高流量的程序,应用要在发送完毕后再发送,以免数据丢包。 一个套接字有两个缓冲区

侯彩桦 1692

深信服桌面云实战:从零部署到高效运维的配置全景指南

本文详细介绍了深信服桌面云从零部署到高效运维的全流程配置指南,涵盖硬件规划、平台部署、虚拟桌面发布、终端管理及性能优化等关键环节。特别强调了双万兆网络架构、分布式存储配置和智能调度功能的应用,帮助用户实现高性能、高可用的虚拟桌面环境。

weixin_28568819的博客 401

Feko仿真GPS微带天线学习笔记

为了优化方便,使参数变量化,所以定义几个变量在CADFEKO左侧浏览器中如图所示定义变量,如下表贴片的尺寸切角尺寸feed =-6.4馈电点距坐标原点的距离sub_w=45基板的宽度sub_d=45基板的长度sub_h=5基板的高度epsR=5.6介电常数损耗角正切。

qq_36521926的博客 3991

muduo_net库源码分析(26-1

Channel是selectable IO channel,负责注册与响应IO 事件,它不拥有file descriptor。 Channel是Acceptor、Connector、EventLoop、TimerQueue、TcpConnection的成员,生命期由后者控制。 时序图 EventLoop头文件 eventl

Riak, Spark, Golang, Erlang, 云存储, 云计算, 数据挖掘 2278

华为OD机试真题 新系统 - WIFI设备网络规划 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 2017

Muduo网络库源码分析(一) EventLoop事件循环(Poller和Channel)

从这一篇博文起,我们开始剖析Muduo网络库的源码,主要结合《Linux多线程服务端编程》和网上的一些学习资料! (一)TCP网络编程的本质:三个半事件 1. 连接的建立,包括服务端接受(accept) 新连接和客户端成功发起(connect) 连接。TCP 连接一旦建立,客户端和服务端是平等的,可以各自收发数据。 2. 连接的断开,包括主动断开(close 或shutdown) 和被动断开

NK_test的博客 7026

Carla运行显示The following component(s) are required to run this program:DirectX Runtime |nvapi64.dll没有被

Carla运行显示The following component(s) are required to run this p 参考: 【1】EPIC 启动游戏提示The following component(s) are required to run this program:... - 『悬赏问答区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cnhttps://www.52pojie.cn/thread-1485651-1-1.html ...

anananajiushiwo的博客 5万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

muduo 网络库源码解析和使用

Muduo库是陈硕开发的Tcp网络编程库,采用了Reactor模型,非常适合网络编程初学者。出于个人学习目的阅读了其源码实现,并梳理了其中核心模块的执行流程,以及试图揣测作者一些部分的实现心得,并从中学到了很多工程实践知识,首次切实感受到多线程的种种困境;

weixin_44835655的博客 1767

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

muduo网络库net源码逐行分析_1

1 muduo::net::EchoServer类 参考EchoServer类 参考 EchoServer 的协作图: [图例] Public 成员函数 EchoServer (EventLoop *loop, const InetAddress &listenAddr) void start () Private 成员函数 void onConnection (const TcpConnectionPtr &conn) void onMe

m0_47178337的博客 691

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Muduo网络库源码分析(二) 定时器TimeQueue,Timer,TimerId

首先,我们先要明白为什么需要设计这样一个定时器类? 在开发Linux网络程序时,通常需要维护多个定时器,如维护客户端心跳时间、检查多个数据包的超时重传等。如果采用Linux的SIGALARM信号实现,则会带来较大的系统开销,且不便于管理。 Muduo 的 TimerQueue 采用了最简单的实现(链表)来管理定时器,它的效率比不上常见的 binary heap 的做法,如果程序中大

NK_test的博客 5915

muduo库net源码分析三(定时器)

让EventLoop 能够处理定时器事件 定时函数 用于让程序等待一段时间或安排计划任务: sleep alarm usleep nanosleep clock_nanosleep getitimer / setitimer timer_create / timer_settime / timer_gettime / timer_delete timerfd_create / timerfd_gettime / timerfd_settime 选择这种方法。 为什么选择timerfd_c

侯彩桦 294

muduo库net源码分析二(类之间的关系)

muduo 网络库相关的类图 白色部分是外部类,对外可见的。灰色部分是内部类,对外不可见。 EventLoop是对事件的抽象 Poller 是对IO 复用的抽象,有两个派生类,PollPoller 对poll 的封装,EPollPoller对epoll的封装 。这个地方是muduo 唯一使用面向对象封装的。 Channel 是对IO事件的注册和响应的封装 。Channel 的Update成员函数负责注册和更新IO的可读可写等事件。Channel 的handleEvent()成员函数是对所发生的IO事

侯彩桦 438

muduo_net源码分析(1):Reactor的关键结构

Muduo网络库简介 muduo是一个基于Reactor模式的现代c++网络库。它主要采用非阻塞_IO模型,基于时间驱动和回调,原生支持多核多线程,适合编写Linux服务端多线程网络应用程序 Reactor的关键结构 Reacor的核心是事件分发机制,也就是将IO复用模型(poll/epoll)那里拿到的io事件分发给各文件描述符的事件处理函数。为了实现这个机制,我们需要编写Channel class和Poller class。下面说明一下这两个类。 1 Channel class Channel是为文件

wenxingxingxing的博客 189

muduo库net源码分析六(Socket 封装)

SocketsOps.h/ SocketsOps.cc 封装了socket相关系统调用(全局函数,位于muduo::net::sockets名称空间中)。 Socket.h/Socket.cc(Socket类) 用RAII方法封装socket file descriptor。 InetAddress.h/InetAddress.cc(InetAddress类) 网际地址sockaddr_in封装 Endian.h 封装了字节序转换函数(全局函数,位于muduo::net::sockets名..

侯彩桦 438

muduo库net源码分析八(TcpServer/TcpConnection)

Acceptor类的主要功能是socket、bind、listen 一般来说,在上层应用程序中,我们不直接使用Acceptor,而是把它作为TcpServer的成员 TcpServer还包含了一个TcpConnection列表 TcpConnection与Acceptor类似,有两个重要的数据成员,Socket与Channel。 #ifndef MUDUO_NET_TCPSERVER_H #define MUDUO_NET_TCPSERVER_H #include <muduo/bas.

侯彩桦 283

muduo_net库源码分析(十一)(EventLoopThread类、EventLoopThreadPool类实现multiple reactors)

一个程序有多个EventLoop,也就是有多个IO线程(one loop per thread)

ShenHang_的博客 321

muduo源码分析:TcpServer类

上篇博文学习了Acceptor class 的实现,它仅仅是对Channel和Socket的简单封装,对使用者来说简单易用。这得益于底层架构Reactor。接下来,开始学习muduo对于建立连接的处理。这属于muduo提到的三个半事件中的第一个。可以想一下,TcpServer class应该也是对Acceptor,Poller的封装。   连接处理过程 首先TcpServer通过Accepto...

amoscykl的博客 679

muduo库net源码分析十三(tcp客户端的支持)

Connector 主动发起连接 带有自动重连功能 #ifndef MUDUO_NET_CONNECTOR_H #define MUDUO_NET_CONNECTOR_H #include <muduo/net/InetAddress.h> #include <boost/enable_shared_from_this.hpp> #include <boost/function.hpp> #include <boost/noncopyable.hpp&gt

侯彩桦 229
下一篇: mysql复制表结构和数据
Buger(8哥)
博客等级 码龄15年 17粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值